Implemented visibility rights for DCI's and collected information
authorzev <zev@netxms.org>
Fri, 10 Nov 2017 11:10:05 +0000 (13:10 +0200)
committerzev <zev@netxms.org>
Fri, 10 Nov 2017 11:13:03 +0000 (13:13 +0200)
50 files changed:
include/netxmsdb.h
src/client/java/netxms-client/src/main/java/org/netxms/client/datacollection/DataCollectionObject.java
src/java/netxms-eclipse/DataCollection/META-INF/MANIFEST.MF
src/java/netxms-eclipse/DataCollection/plugin.xml
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java [new file with mode: 0644]
src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java [new file with mode: 0644]
src/server/core/accesspoint.cpp
src/server/core/agent.cpp
src/server/core/agent_policy.cpp
src/server/core/ap_config.cpp
src/server/core/ap_logparser.cpp
src/server/core/bizservice.cpp
src/server/core/chassis.cpp
src/server/core/cluster.cpp
src/server/core/condition.cpp
src/server/core/container.cpp
src/server/core/dashboard.cpp
src/server/core/datacoll.cpp
src/server/core/dc_nxsl.cpp
src/server/core/dcitem.cpp
src/server/core/dcobject.cpp
src/server/core/dcst.cpp
src/server/core/dctable.cpp
src/server/core/dctarget.cpp
src/server/core/interface.cpp
src/server/core/mdsession.cpp
src/server/core/mobile.cpp
src/server/core/netmap.cpp
src/server/core/netobj.cpp
src/server/core/netsrv.cpp
src/server/core/node.cpp
src/server/core/nodelink.cpp
src/server/core/npe.cpp
src/server/core/rack.cpp
src/server/core/sensor.cpp
src/server/core/session.cpp
src/server/core/slmcheck.cpp
src/server/core/subnet.cpp
src/server/core/svccontainer.cpp
src/server/core/template.cpp
src/server/core/vpnconn.cpp
src/server/core/zone.cpp
src/server/include/nms_dcoll.h
src/server/include/nms_objects.h
src/server/tools/nxdbmgr/upgrade_v22.cpp
src/server/tools/nxdbmgr/upgrade_v30.cpp
webui/webapp/DataCollection/META-INF/MANIFEST.MF
webui/webapp/DataCollection/plugin.xml
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java [new file with mode: 0644]
webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java [new file with mode: 0644]

index bb31699..a6eebbc 100644 (file)
@@ -25,7 +25,7 @@
 
 #define DB_LEGACY_SCHEMA_VERSION       700
 #define DB_SCHEMA_VERSION_MAJOR        30
-#define DB_SCHEMA_VERSION_MINOR        11
+#define DB_SCHEMA_VERSION_MINOR        12
 
 #define DB_SCHEMA_VERSION_V30_MINOR    DB_SCHEMA_VERSION_MINOR
 
index 5d72414..a45e962 100644 (file)
@@ -19,7 +19,9 @@
 package org.netxms.client.datacollection;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import org.netxms.base.NXCPCodes;
 import org.netxms.base.NXCPMessage;
 import org.netxms.client.constants.AgentCacheMode;
@@ -99,6 +101,7 @@ public abstract class DataCollectionObject
    private int instanceDiscoveryMethod;
    private String instanceDiscoveryData;
    private String instanceDiscoveryFilter;
+   private List<Long> accessRightList;
 
        /**
         * Create data collection object from NXCP message
@@ -138,6 +141,12 @@ public abstract class DataCollectionObject
       instanceDiscoveryMethod = msg.getFieldAsInt32(NXCPCodes.VID_INSTD_METHOD);
       instanceDiscoveryData = msg.getFieldAsString(NXCPCodes.VID_INSTD_DATA);
       instanceDiscoveryFilter = msg.getFieldAsString(NXCPCodes.VID_INSTD_FILTER);      
+
+      Long arr[] = msg.getFieldAsUInt32ArrayEx(NXCPCodes.VID_ACL);
+      if(arr == null)
+         accessRightList = new ArrayList<Long>(0);
+      else
+         accessRightList = new ArrayList<Long>(Arrays.asList(arr));
        }
 
        /**
@@ -167,6 +176,7 @@ public abstract class DataCollectionObject
                schedules = new ArrayList<String>(0);
                comments = "";
       instance = "";
+      accessRightList = new ArrayList<Long>(0);
        }
        
        /**
@@ -206,6 +216,8 @@ public abstract class DataCollectionObject
          msg.setField(NXCPCodes.VID_INSTD_DATA, instanceDiscoveryData);
       if (instanceDiscoveryFilter != null)
          msg.setField(NXCPCodes.VID_INSTD_FILTER, instanceDiscoveryFilter);
+      
+      msg.setField(NXCPCodes.VID_ACL, accessRightList.toArray(new Long[accessRightList.size()]));
        }
 
        /**
@@ -702,4 +714,14 @@ public abstract class DataCollectionObject
    {
       this.instanceDiscoveryFilter = instanceDiscoveryFilter;
    }
+
+   public List<Long> getAccessList()
+   {
+      return accessRightList;
+   }
+
+   public void setAccessList(List<Long> list)
+   {
+      accessRightList = list;
+   }
 }
index c3cac59..671f99d 100644 (file)
@@ -18,7 +18,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.8.2",
  org.netxms.ui.eclipse.nxsl;bundle-version="2.0.7",
  org.netxms.ui.eclipse.charts;bundle-version="2.0.5",
  org.netxms.ui.eclipse.objecttools;bundle-version="2.0.8",
- org.netxms.ui.base;bundle-version="2.1.2"
+ org.netxms.ui.base;bundle-version="2.1.2",
+ org.netxms.ui.eclipse.usermanager;bundle-version="2.0.8"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.netxms.ui.eclipse.datacollection.actions,
index fbe16a6..dd36b9b 100644 (file)
               </instanceof>
            </enabledWhen>
         </page>
+        <page
+              class="org.netxms.ui.eclipse.datacollection.propertypages.VisibilityControl"
+              id="org.netxms.ui.eclipse.datacollection.propertypages.InstanceDiscovery#50"
+              name="Visibility">
+           <enabledWhen>
+              <instanceof
+                    value="org.netxms.client.datacollection.DataCollectionObject">
+              </instanceof>
+           </enabledWhen>
+        </page>
    </extension>
 
   <extension
diff --git a/src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java b/src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java
new file mode 100644 (file)
index 0000000..2991190
--- /dev/null
@@ -0,0 +1,244 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2011 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.datacollection.propertypages;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.netxms.client.NXCSession;
+import org.netxms.client.datacollection.DataCollectionObject;
+import org.netxms.client.users.AbstractUserObject;
+import org.netxms.client.users.User;
+import org.netxms.ui.eclipse.datacollection.api.DataCollectionObjectEditor;
+import org.netxms.ui.eclipse.datacollection.propertypages.helpers.DCIPropertyPageDialog;
+import org.netxms.ui.eclipse.datacollection.propertypages.helpers.VisibilityUserListLabelProvider;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+import org.netxms.ui.eclipse.tools.ObjectLabelComparator;
+import org.netxms.ui.eclipse.tools.WidgetHelper;
+import org.netxms.ui.eclipse.usermanager.dialogs.SelectUserDialog;
+
+/**
+ * "Access Control" property page
+ */
+public class VisibilityControl extends DCIPropertyPageDialog
+{
+   private DataCollectionObjectEditor editor;
+   private DataCollectionObject dco;
+       private Set<AbstractUserObject> acl = new HashSet<AbstractUserObject>();
+       private TableViewer viewer;
+       private Button buttonAdd;
+       private Button buttonRemove;
+       private static final String info[] = {"Inherited from object access rights"};
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       public void createControl(Composite parent)
+       {
+               noDefaultAndApplyButton();
+               super.createControl(parent);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       protected Control createContents(Composite parent)
+       {
+      editor = (DataCollectionObjectEditor)getElement().getAdapter(DataCollectionObjectEditor.class);
+      dco = editor.getObject();      
+
+      // Initiate loading of user manager plugin if it was not loaded before
+      Platform.getAdapterManager().loadAdapter(new User(""), "org.eclipse.ui.model.IWorkbenchAdapter"); //$NON-NLS-1$ //$NON-NLS-2$
+               
+               // Build internal copy of access list
+               final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
+               for(Long uid : dco.getAccessList())
+               {
+                       AbstractUserObject o = session.findUserDBObjectById(uid);
+                       if (o != null)
+                               acl.add(o);
+               }
+               
+               Composite dialogArea = new Composite(parent, SWT.NONE);
+               
+               GridLayout layout = new GridLayout();
+               layout.verticalSpacing = WidgetHelper.INNER_SPACING;
+               layout.marginWidth = 0;
+               layout.marginHeight = 0;
+               dialogArea.setLayout(layout);
+               
+               Label label = new Label(dialogArea, SWT.NONE);
+               label.setText("Visible to:");
+               
+               viewer = new TableViewer(dialogArea, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
+               viewer.setContentProvider(new ArrayContentProvider());
+               viewer.setLabelProvider(new VisibilityUserListLabelProvider());
+               viewer.setComparator(new ObjectLabelComparator((ILabelProvider)viewer.getLabelProvider()));
+               viewer.getTable().setSortDirection(SWT.UP);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = SWT.FILL;
+               gd.verticalAlignment = SWT.FILL;
+               gd.grabExcessHorizontalSpace = true;
+               gd.grabExcessVerticalSpace = true;
+               gd.heightHint = 300;
+               viewer.getTable().setLayoutData(gd);
+               viewer.setInput(acl.toArray());
+               updateInfoNote();
+               
+      Composite buttons = new Composite(dialogArea, SWT.NONE);
+      RowLayout buttonLayout = new RowLayout();
+      buttonLayout.type = SWT.HORIZONTAL;
+      buttonLayout.pack = false;
+      buttonLayout.marginWidth = 0;
+      buttons.setLayout(buttonLayout);
+      gd = new GridData();
+      gd.horizontalAlignment = SWT.RIGHT;
+      gd.verticalIndent = WidgetHelper.OUTER_SPACING - WidgetHelper.INNER_SPACING;
+      buttons.setLayoutData(gd);
+
+      buttonAdd = new Button(buttons, SWT.PUSH);
+      buttonAdd.setText("Add");
+      buttonAdd.addSelectionListener(new SelectionListener() {
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               addUser();
+                       }
+      });
+      RowData rd = new RowData();
+      rd.width = WidgetHelper.BUTTON_WIDTH_HINT;
+      buttonAdd.setLayoutData(rd);
+               
+      buttonRemove = new Button(buttons, SWT.PUSH);
+      buttonRemove.setText("Remove");
+      buttonRemove.addSelectionListener(new SelectionListener() {
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               removeUsers();
+                       }
+      });
+      rd = new RowData();
+      rd.width = WidgetHelper.BUTTON_WIDTH_HINT;
+      buttonRemove.setLayoutData(rd);
+               
+               return dialogArea;
+       }
+       
+       /**
+        * Adds info element to the list if empty
+        */
+       public void updateInfoNote()
+       {
+      if(acl.size() == 0)
+      {
+         viewer.setInput(info);
+      }
+       }
+       
+       /**
+        * Add users to ACL
+        */
+       public void addUser()
+       {
+               SelectUserDialog dlg = new SelectUserDialog(getShell(), AbstractUserObject.class);
+               if (dlg.open() == Window.OK)
+               {
+                       for(AbstractUserObject o : dlg.getSelection())
+                               acl.add(o);
+                       viewer.setInput(acl.toArray());
+               }
+       }
+       
+       /**
+        * Remove users from ACL
+        */
+       public void removeUsers()
+       {
+               IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+               for(Object o : selection.toList())
+                       acl.remove(o);
+               viewer.setInput(acl.toArray());
+               updateInfoNote();
+       }
+       
+       /**
+        * Apply changes
+        * 
+        * @param isApply true if update operation caused by "Apply" button
+        */
+       protected void applyChanges(final boolean isApply)
+       {
+               List<Long> list = new ArrayList<Long>(acl.size());
+               for(AbstractUserObject o : acl)
+                       list.add(o.getId());
+               dco.setAccessList(list);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#performApply()
+        */
+       @Override
+       protected void performApply()
+       {
+               applyChanges(true);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#performOk()
+        */
+       @Override
+       public boolean performOk()
+       {
+               applyChanges(false);
+               return true;
+       }
+}
diff --git a/src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java b/src/java/netxms-eclipse/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java
new file mode 100644 (file)
index 0000000..e619500
--- /dev/null
@@ -0,0 +1,55 @@
+package org.netxms.ui.eclipse.datacollection.propertypages.helpers;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * Label provider for visibility table. 
+ * Uses default workbench label provider for user object and 
+ * implements own for String like with warning. 
+ */
+public class VisibilityUserListLabelProvider extends LabelProvider
+{
+   private WorkbenchLabelProvider workbenchLabelProvider;
+   
+   /**
+    * Default constructor
+    */
+   public VisibilityUserListLabelProvider()
+   {
+      workbenchLabelProvider = new WorkbenchLabelProvider();
+   }    
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+    */
+   @Override
+   public Image getImage(Object element)
+   {
+      if(element instanceof String)
+         return null;
+      return workbenchLabelProvider.getImage(element);
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+    */
+   @Override
+   public String getText(Object element)
+   {
+      if(element instanceof String)
+         return (String)element;
+      return workbenchLabelProvider.getText(element);
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose()
+    */
+   @Override
+   public void dispose()
+   {
+      workbenchLabelProvider.dispose();
+      super.dispose();
+   }
+}
index 871660d..408af36 100644 (file)
@@ -207,9 +207,9 @@ bool AccessPoint::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create CSCP message with object's data
  */
-void AccessPoint::fillMessageInternal(NXCPMessage *msg)
+void AccessPoint::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   DataCollectionTarget::fillMessageInternal(msg);
+   DataCollectionTarget::fillMessageInternal(msg, userId);
    msg->setField(VID_IP_ADDRESS, m_ipAddress);
        msg->setField(VID_NODE_ID, m_nodeId);
        msg->setField(VID_MAC_ADDR, m_macAddr, MAC_ADDR_LENGTH);
index 64b4384..e86ef87 100644 (file)
@@ -293,7 +293,7 @@ void AgentConnectionEx::onDataPush(NXCPMessage *msg)
          if (target != NULL)
          {
                      DbgPrintf(5, _T("%s: agent data push: %s=%s"), target->getName(), name, value);
-                     DCObject *dci = target->getDCObjectByName(name);
+                     DCObject *dci = target->getDCObjectByName(name, 0);
                      if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM) && (dci->getDataSource() == DS_PUSH_AGENT) && (dci->getStatus() == ITEM_STATUS_ACTIVE))
                      {
                              DbgPrintf(5, _T("%s: agent data push: found DCI %d"), target->getName(), dci->getId());
@@ -642,7 +642,7 @@ UINT32 AgentConnectionEx::processCollectedData(NXCPMessage *msg)
    }
 
    UINT32 dciId = msg->getFieldAsUInt32(VID_DCI_ID);
-   DCObject *dcObject = target->getDCObjectById(dciId);
+   DCObject *dcObject = target->getDCObjectById(dciId, 0);
    if (dcObject == NULL)
    {
       debugPrintf(5, _T("AgentConnectionEx::processCollectedData: cannot find DCI with ID %d on object %s [%d]"),
@@ -801,7 +801,7 @@ UINT32 AgentConnectionEx::processBulkCollectedData(NXCPMessage *request, NXCPMes
       }
 
       UINT32 dciId = request->getFieldAsUInt32(fieldId);
-      DCObject *dcObject = target->getDCObjectById(dciId);
+      DCObject *dcObject = target->getDCObjectById(dciId, 0);
       if (dcObject == NULL)
       {
          debugPrintf(5, _T("AgentConnectionEx::processBulkCollectedData: cannot find DCI with ID %d on object %s [%d] (element %d)"),
index fc3798c..5b0c09c 100644 (file)
@@ -206,9 +206,9 @@ bool AgentPolicy::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
 /**
  * Create NXCP message with policy data
  */
-void AgentPolicy::fillMessageInternal(NXCPMessage *msg)
+void AgentPolicy::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-       NetObj::fillMessageInternal(msg);
+       NetObj::fillMessageInternal(msg, userId);
        msg->setField(VID_POLICY_TYPE, (WORD)m_policyType);
        msg->setField(VID_VERSION, m_version);
 }
index 05356ac..6e92a0d 100644 (file)
@@ -133,9 +133,9 @@ bool AgentPolicyConfig::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
 /**
  * Create NXCP message with policy data
  */
-void AgentPolicyConfig::fillMessageInternal(NXCPMessage *msg)
+void AgentPolicyConfig::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   AgentPolicy::fillMessageInternal(msg);
+   AgentPolicy::fillMessageInternal(msg, userId);
        msg->setField(VID_CONFIG_FILE_DATA, CHECK_NULL_EX(m_fileContent));
 }
 
index 3561cc1..79e465b 100644 (file)
@@ -133,9 +133,9 @@ bool AgentPolicyLogParser::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
 /**
  * Create NXCP message with policy data
  */
-void AgentPolicyLogParser::fillMessageInternal(NXCPMessage *msg)
+void AgentPolicyLogParser::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   AgentPolicy::fillMessageInternal(msg);
+   AgentPolicy::fillMessageInternal(msg, userId);
        msg->setField(VID_CONFIG_FILE_DATA, CHECK_NULL_EX(m_fileContent));
 }
 
index 703e214..6f56b27 100644 (file)
@@ -157,9 +157,9 @@ bool BusinessService::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void BusinessService::fillMessageInternal(NXCPMessage *pMsg)
+void BusinessService::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   ServiceContainer::fillMessageInternal(pMsg);
+   ServiceContainer::fillMessageInternal(pMsg, userId);
 }
 
 /**
index 0b608ec..3666395 100644 (file)
@@ -154,9 +154,9 @@ void Chassis::updateControllerBinding()
 /**
  * Create NXCP message with object's data
  */
-void Chassis::fillMessageInternal(NXCPMessage *msg)
+void Chassis::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   DataCollectionTarget::fillMessageInternal(msg);
+   DataCollectionTarget::fillMessageInternal(msg, userId);
    msg->setField(VID_CONTROLLER_ID, m_controllerId);
    msg->setField(VID_RACK_ID, m_rackId);
    msg->setField(VID_RACK_IMAGE, m_rackImage);
index 0308abf..1d5e775 100644 (file)
@@ -382,11 +382,11 @@ bool Cluster::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create CSCP message with object's data
  */
-void Cluster::fillMessageInternal(NXCPMessage *pMsg)
+void Cluster::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
        UINT32 i, dwId;
 
-   DataCollectionTarget::fillMessageInternal(pMsg);
+   DataCollectionTarget::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_CLUSTER_TYPE, m_dwClusterType);
        pMsg->setField(VID_ZONE_UIN, m_zoneUIN);
 
@@ -796,7 +796,7 @@ UINT32 Cluster::collectAggregatedData(DCItem *item, TCHAR *buffer)
          continue;
 
       Node *node = (Node *)m_childList->get(i);
-      DCObject *dco = node->getDCObjectByTemplateId(item->getId());
+      DCObject *dco = node->getDCObjectByTemplateId(item->getId(), 0);
       if ((dco != NULL) &&
           (dco->getType() == DCO_TYPE_ITEM) &&
           (dco->getStatus() == ITEM_STATUS_ACTIVE) &&
@@ -860,7 +860,7 @@ UINT32 Cluster::collectAggregatedData(DCTable *table, Table **result)
          continue;
 
       Node *node = (Node *)m_childList->get(i);
-      DCObject *dco = node->getDCObjectByTemplateId(table->getId());
+      DCObject *dco = node->getDCObjectByTemplateId(table->getId(), 0);
       if ((dco != NULL) &&
           (dco->getType() == DCO_TYPE_TABLE) &&
           (dco->getStatus() == ITEM_STATUS_ACTIVE) &&
index f024903..6ac9670 100644 (file)
@@ -243,9 +243,9 @@ bool ConditionObject::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message from object
  */
-void ConditionObject::fillMessageInternal(NXCPMessage *pMsg)
+void ConditionObject::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
 
    pMsg->setField(VID_SCRIPT, CHECK_NULL_EX(m_scriptSource));
    pMsg->setField(VID_ACTIVATION_EVENT, m_activationEventCode);
@@ -406,7 +406,7 @@ void ConditionObject::check()
       {
          if (pObject->getObjectClass() == OBJECT_NODE)
          {
-            DCObject *pItem = ((Node *)pObject)->getDCObjectById(m_dciList[i].id);
+            DCObject *pItem = ((Node *)pObject)->getDCObjectById(m_dciList[i].id, 0);
             if (pItem != NULL)
             {
                if (pItem->getType() == DCO_TYPE_ITEM)
index 6ae65a7..606cc5d 100644 (file)
@@ -245,9 +245,9 @@ void Container::calculateCompoundStatus(BOOL bForcedRecalc)
 /**
  * Create NXCP message with object's data
  */
-void Container::fillMessageInternal(NXCPMessage *msg)
+void Container::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(msg);
+   NetObj::fillMessageInternal(msg, userId);
        msg->setField(VID_AUTOBIND_FILTER, CHECK_NULL_EX(m_bindFilterSource));
 }
 
index a7c2e9a..1670c8b 100644 (file)
@@ -182,9 +182,9 @@ bool Dashboard::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void Dashboard::fillMessageInternal(NXCPMessage *msg)
+void Dashboard::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-       Container::fillMessageInternal(msg);
+       Container::fillMessageInternal(msg, userId);
 
        msg->setField(VID_NUM_COLUMNS, (WORD)m_numColumns);
        msg->setField(VID_NUM_ELEMENTS, (UINT32)m_elements->size());
index 0c925a3..8f0acf9 100644 (file)
@@ -517,7 +517,7 @@ THREAD_RESULT THREAD_CALL CacheLoader(void *arg)
       if ((object != NULL) && object->isDataCollectionTarget())
       {
          object->incRefCount();
-         DCObject *dci = static_cast<DataCollectionTarget*>(object)->getDCObjectById(ref->getId(), true);
+         DCObject *dci = static_cast<DataCollectionTarget*>(object)->getDCObjectById(ref->getId(), 0, true);
          if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
          {
             nxlog_debug_tag(_T("obj.dc.cache"), 6, _T("Loading cache for DCI %s [%d] on %s [%d]"),
@@ -667,7 +667,7 @@ int GetDCObjectType(UINT32 nodeId, UINT32 dciId)
    Node *node = (Node *)FindObjectById(nodeId, OBJECT_NODE);
    if (node != NULL)
    {
-      DCObject *dco = node->getDCObjectById(dciId);
+      DCObject *dco = node->getDCObjectById(dciId, 0);
       if (dco != NULL)
       {
          return dco->getType();
index 74644ea..bde7dcb 100644 (file)
@@ -41,7 +41,7 @@ static int F_GetDCIObject(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NX
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32());
+       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32(), 0);
        if (dci != NULL)
        {
                *ppResult = dci->createNXSLObject();
@@ -71,7 +71,7 @@ static int GetDCIValueImpl(bool rawValue, int argc, NXSL_Value **argv, NXSL_Valu
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32());
+       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32(), 0);
        if (dci != NULL)
    {
       if (dci->getType() == DCO_TYPE_ITEM)
@@ -133,7 +133,7 @@ static int GetDciValueExImpl(bool byName, int argc, NXSL_Value **argv, NXSL_Valu
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = byName ? node->getDCObjectByName(argv[1]->getValueAsCString()) : node->getDCObjectByDescription(argv[1]->getValueAsCString());
+       DCObject *dci = byName ? node->getDCObjectByName(argv[1]->getValueAsCString(), 0) : node->getDCObjectByDescription(argv[1]->getValueAsCString(), 0);
        if (dci != NULL)
    {
       if (dci->getType() == DCO_TYPE_ITEM)
@@ -195,7 +195,7 @@ static int F_FindDCIByName(int argc, NXSL_Value **argv, NXSL_Value **ppResult, N
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectByName(argv[1]->getValueAsCString());
+       DCObject *dci = node->getDCObjectByName(argv[1]->getValueAsCString(), 0);
        *ppResult = (dci != NULL) ? new NXSL_Value(dci->getId()) : new NXSL_Value((UINT32)0);
        return 0;
 }
@@ -217,7 +217,7 @@ static int F_FindDCIByDescription(int argc, NXSL_Value **argv, NXSL_Value **ppRe
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectByDescription(argv[1]->getValueAsCString());
+       DCObject *dci = node->getDCObjectByDescription(argv[1]->getValueAsCString(), 0);
        *ppResult = (dci != NULL) ? new NXSL_Value(dci->getId()) : new NXSL_Value((UINT32)0);
        return 0;
 }
@@ -260,7 +260,7 @@ static int F_FindAllDCIs(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXS
    }
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       *ppResult = node->getAllDCObjectsForNXSL(nameFilter, descriptionFilter);
+       *ppResult = node->getAllDCObjectsForNXSL(nameFilter, descriptionFilter, 0);
        return 0;
 }
 
@@ -281,7 +281,7 @@ static int F_GetDCIValueStat(int argc, NXSL_Value **argv, NXSL_Value **ppResult,
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32());
+       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32(), 0);
        if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
        {
       TCHAR *result = ((DCItem *)dci)->getAggregateValue(func, argv[2]->getValueAsInt32(), argv[3]->getValueAsInt32());
@@ -354,7 +354,7 @@ static int F_GetDCIValues(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NX
                return NXSL_ERR_BAD_CLASS;
 
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
-       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32());
+       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32(), 0);
        if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
        {
                DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
@@ -489,7 +489,7 @@ static int F_PushDCIData(int argc, NXSL_Value **argv, NXSL_Value **ppResult, NXS
        DataCollectionTarget *node = (DataCollectionTarget *)object->getData();
 
    bool success = false;
-       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32());
+       DCObject *dci = node->getDCObjectById(argv[1]->getValueAsUInt32(), 0);
    if ((dci != NULL) && (dci->getDataSource() == DS_PUSH_AGENT))
    {
       time_t t = time(NULL);
index c12597d..d41f6c8 100644 (file)
@@ -101,7 +101,7 @@ DCItem::DCItem(const DCItem *pSrc) : DCObject(pSrc)
  *    delta_calculation,transformation,template_id,description,instance,
  *    template_item_id,flags,resource_id,proxy_node,base_units,unit_multiplier,
  *    custom_units_name,perftab_settings,system_tag,snmp_port,snmp_raw_value_type,
- *    instd_method,instd_data,instd_filter,samples,comments,guid,npe_name
+ *    instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights
  */
 DCItem::DCItem(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DCObject()
 {
@@ -148,6 +148,16 @@ DCItem::DCItem(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DC
    m_comments = DBGetField(hResult, iRow, 27, NULL, 0);
    m_guid = DBGetFieldGUID(hResult, iRow, 28);
    DBGetField(hResult, iRow, 29, m_predictionEngine, MAX_NPE_NAME_LEN);
+   //set visibility rights
+   pszTmp = DBGetField(hResult, iRow, 30, NULL, 0);
+   StringList list;
+   list.splitAndAdd(pszTmp, _T(","));
+   for(int i = 0; i < list.size(); i++)
+   {
+      if(*(list.get(i)) != 0)
+         m_visibilityRights->add(_tcstoll(list.get(i), NULL, 0));
+   }
+   free(pszTmp);
 
    // Load last raw value from database
        TCHAR szQuery[256];
@@ -322,7 +332,7 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
                           _T("unit_multiplier=?,custom_units_name=?,perftab_settings=?,")
                      _T("system_tag=?,snmp_port=?,snmp_raw_value_type=?,")
                                          _T("instd_method=?,instd_data=?,instd_filter=?,samples=?,")
-                                         _T("comments=?,guid=?,npe_name=? WHERE item_id=?"));
+                                         _T("comments=?,guid=?,npe_name=?,visibility_rights=? WHERE item_id=?"));
        }
    else
        {
@@ -332,8 +342,8 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
                  _T("transformation,description,instance,template_item_id,flags,")
                  _T("resource_id,proxy_node,base_units,unit_multiplier,")
                           _T("custom_units_name,perftab_settings,system_tag,snmp_port,snmp_raw_value_type,")
-                                         _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,item_id) VALUES ")
-                          _T("(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+                                         _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights,item_id) VALUES ")
+                          _T("(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
        }
        if (hStmt == NULL)
                return false;
@@ -370,7 +380,16 @@ bool DCItem::saveToDatabase(DB_HANDLE hdb)
    DBBind(hStmt, 28, DB_SQLTYPE_TEXT, m_comments, DB_BIND_STATIC);
    DBBind(hStmt, 29, DB_SQLTYPE_VARCHAR, m_guid);
    DBBind(hStmt, 30, DB_SQLTYPE_VARCHAR, m_predictionEngine, DB_BIND_STATIC);
-       DBBind(hStmt, 31, DB_SQLTYPE_INTEGER, m_id);
+   String tmp;
+   int size = m_visibilityRights->size();
+   for(int i = 0; i < size; i++)
+   {
+      tmp.append(m_visibilityRights->get(i));
+      if(i != (size - 1))
+         tmp.append(_T(','));
+   }
+   DBBind(hStmt, 31, DB_SQLTYPE_VARCHAR, tmp, DB_BIND_STATIC);
+       DBBind(hStmt, 32, DB_SQLTYPE_INTEGER, m_id);
 
    bool bResult = DBExecute(hStmt);
        DBFreeStatement(hStmt);
index 7f1e985..0730bd7 100644 (file)
@@ -70,6 +70,7 @@ DCObject::DCObject()
    m_instanceFilterSource = NULL;
    m_instanceFilter = NULL;
    m_instance[0] = 0;
+   m_visibilityRights = new IntegerArray<UINT32>();
 }
 
 /**
@@ -115,6 +116,7 @@ DCObject::DCObject(const DCObject *pSrc)
    m_instanceFilter = NULL;
    setInstanceFilter(pSrc->m_instanceFilterSource);
    _tcscpy(m_instance, pSrc->m_instance);
+   m_visibilityRights = new IntegerArray<UINT32>(pSrc->m_visibilityRights);
 }
 
 /**
@@ -160,6 +162,7 @@ DCObject::DCObject(UINT32 dwId, const TCHAR *szName, int iSource,
    m_instanceFilterSource = NULL;
    m_instanceFilter = NULL;
    m_instance[0] = 0;
+   m_visibilityRights = new IntegerArray<UINT32>();
 }
 
 /**
@@ -225,6 +228,7 @@ DCObject::DCObject(ConfigEntry *config, Template *owner)
    m_instanceFilter = NULL;
    setInstanceFilter(config->getSubEntryValue(_T("instanceFilter")));
    nx_strncpy(m_instance, config->getSubEntryValue(_T("instance"), 0, _T("")), MAX_DB_STRING);
+   m_visibilityRights = new IntegerArray<UINT32>();
 }
 
 /**
@@ -241,6 +245,7 @@ DCObject::~DCObject()
    free(m_instanceDiscoveryData);
    free(m_instanceFilterSource);
    delete m_instanceFilter;
+   delete m_visibilityRights;
 }
 
 /**
@@ -692,6 +697,7 @@ void DCObject::createMessage(NXCPMessage *pMsg)
    if (m_instanceFilterSource != NULL)
       pMsg->setField(VID_INSTD_FILTER, m_instanceFilterSource);
    pMsg->setField(VID_INSTANCE, m_instance);
+   pMsg->setFieldFromInt32Array(VID_ACL, m_visibilityRights);
    unlock();
 }
 
@@ -754,6 +760,8 @@ void DCObject::updateFromMessage(NXCPMessage *pMsg)
    setInstanceFilter(pszStr);
    safe_free(pszStr);
    pMsg->getFieldAsString(VID_INSTANCE, m_instance, MAX_DB_STRING);
+   m_visibilityRights->clear();
+   pMsg->getFieldAsInt32Array(VID_ACL, m_visibilityRights);
 
        unlock();
 }
@@ -1249,6 +1257,34 @@ void DCObject::setInstanceFilter(const TCHAR *pszScript)
 }
 
 /**
+ * Checks if this DCO object is visible by current user
+ */
+bool DCObject::hasAccess(UINT32 userId)
+{
+   if(m_visibilityRights->isEmpty())
+      return true;
+
+   if(userId == 0)
+      return true;
+
+   for(int i = 0; i < m_visibilityRights->size(); i++)
+   {
+      UINT32 id = m_visibilityRights->get(i);
+      if((id & GROUP_FLAG) != 0)
+      {
+         if(CheckUserMembership(userId, id))
+            return true;
+      }
+      else
+      {
+         if(id == userId)
+            return true;
+      }
+   }
+   return false;
+}
+
+/**
  * Serialize object to JSON
  */
 json_t *DCObject::toJson()
@@ -1282,6 +1318,7 @@ json_t *DCObject::toJson()
    json_object_set_new(root, "instanceDiscoveryData", json_string_t(m_instanceDiscoveryData));
    json_object_set_new(root, "instanceFilter", json_string_t(m_instanceFilterSource));
    json_object_set_new(root, "instance", json_string_t(m_instance));
+   json_object_set_new(root, "visibility", m_visibilityRights->toJson());
    return root;
 }
 
index 52a89aa..8cf1b18 100644 (file)
@@ -436,7 +436,7 @@ Table *QuerySummaryTable(LONG tableId, SummaryTable *adHocDefinition, UINT32 bas
 
       if (tableDefinition->filter((DataCollectionTarget *)obj))
       {
-         ((DataCollectionTarget *)obj)->getDciValuesSummary(tableDefinition, tableData);
+         ((DataCollectionTarget *)obj)->getDciValuesSummary(tableDefinition, tableData, userId);
       }
       obj->decRefCount();
    }
index bb4b7d6..e2385ab 100644 (file)
@@ -160,7 +160,7 @@ DCTable::DCTable(UINT32 id, const TCHAR *name, int source, int pollingInterval,
  *    item_id,template_id,template_item_id,name,
  *    description,flags,source,snmp_port,polling_interval,retention_time,
  *    status,system_tag,resource_id,proxy_node,perftab_settings,
- *    transformation_script,comments,guid
+ *    transformation_script,comments,guid,visibility_rights
  */
 DCTable::DCTable(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) : DCObject()
 {
@@ -217,6 +217,16 @@ DCTable::DCTable(DB_HANDLE hdb, DB_RESULT hResult, int iRow, Template *pNode) :
    setInstanceFilter(pszTmp);
    free(pszTmp);
    DBGetField(hResult, iRow, 21, m_instance, MAX_DB_STRING);
+   //set visibility rights
+   pszTmp = DBGetField(hResult, iRow, 21, NULL, 0);
+   StringList list;
+   list.splitAndAdd(pszTmp, _T(","));
+   for(int i = 0; i < list.size(); i++)
+   {
+      if(*(list.get(i)) != 0)
+         m_visibilityRights->add(_tcstoll(list.get(i), NULL, 0));
+   }
+   free(pszTmp);
 }
 
 /**
@@ -489,7 +499,7 @@ bool DCTable::saveToDatabase(DB_HANDLE hdb)
                                       _T("description=?,flags=?,source=?,snmp_port=?,polling_interval=?,")
                              _T("retention_time=?,status=?,system_tag=?,resource_id=?,proxy_node=?,")
                                                                          _T("perftab_settings=?,transformation_script=?,comments=?,guid=?,")
-                                                                         _T("instd_method=?,instd_data=?,instd_filter=?,instance=? WHERE item_id=?"));
+                                                                         _T("instd_method=?,instd_data=?,instd_filter=?,instance=?,visibility_rights=? WHERE item_id=?"));
        }
        else
        {
@@ -497,8 +507,8 @@ bool DCTable::saveToDatabase(DB_HANDLE hdb)
                                       _T("description,flags,source,snmp_port,polling_interval,")
                                       _T("retention_time,status,system_tag,resource_id,proxy_node,perftab_settings,")
                                                                          _T("transformation_script,comments,guid, ")
-                                                                         _T("instd_method,instd_data,instd_filter,instance,item_id) ")
-                                                                         _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
+                                                                         _T("instd_method,instd_data,instd_filter,instance,visibility_rights,item_id) ")
+                                                                         _T("VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"));
        }
        if (hStmt == NULL)
                return FALSE;
@@ -527,7 +537,16 @@ bool DCTable::saveToDatabase(DB_HANDLE hdb)
    DBBind(hStmt, 20, DB_SQLTYPE_VARCHAR, m_instanceDiscoveryData, DB_BIND_STATIC);
    DBBind(hStmt, 21, DB_SQLTYPE_TEXT, m_instanceFilterSource, DB_BIND_STATIC);
    DBBind(hStmt, 22, DB_SQLTYPE_VARCHAR, m_instance, DB_BIND_STATIC);
-   DBBind(hStmt, 23, DB_SQLTYPE_INTEGER, m_id);
+   String tmp;
+   int size = m_visibilityRights->size();
+   for(int i = 0; i < size; i++)
+   {
+      tmp.append(m_visibilityRights->get(i));
+      if(i != (size - 1))
+         tmp.append(_T(','));
+   }
+   DBBind(hStmt, 23, DB_SQLTYPE_VARCHAR, tmp, DB_BIND_STATIC);
+   DBBind(hStmt, 24, DB_SQLTYPE_INTEGER, m_id);
 
        bool result = DBExecute(hStmt);
        DBFreeStatement(hStmt);
index fb569b0..e1c265a 100644 (file)
@@ -93,17 +93,17 @@ bool DataCollectionTarget::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void DataCollectionTarget::fillMessageInternal(NXCPMessage *msg)
+void DataCollectionTarget::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   Template::fillMessageInternal(msg);
+   Template::fillMessageInternal(msg, userId);
 }
 
 /**
  * Create NXCP message with object's data - stage 2
  */
-void DataCollectionTarget::fillMessageInternalStage2(NXCPMessage *msg)
+void DataCollectionTarget::fillMessageInternalStage2(NXCPMessage *msg, UINT32 userId)
 {
-   Template::fillMessageInternalStage2(msg);
+   Template::fillMessageInternalStage2(msg, userId);
 
    // Sent all DCIs marked for display on overview page or in tooltips
    UINT32 fieldIdOverview = VID_OVERVIEW_DCI_LIST_BASE;
@@ -116,7 +116,8 @@ void DataCollectionTarget::fillMessageInternalStage2(NXCPMessage *msg)
       DCObject *dci = m_dcObjects->get(i);
       if ((dci->getType() == DCO_TYPE_ITEM) &&
           (dci->getStatus() == ITEM_STATUS_ACTIVE) &&
-          (((DCItem *)dci)->getInstanceDiscoveryMethod() == IDM_NONE))
+          (((DCItem *)dci)->getInstanceDiscoveryMethod() == IDM_NONE) &&
+          dci->hasAccess(userId))
                {
          if  (dci->isShowInObjectOverview())
          {
@@ -387,7 +388,7 @@ void DataCollectionTarget::cleanDeletedTemplateItems(UINT32 dwTemplateId, UINT32
       }
 
    for(i = 0; i < dwNumDeleted; i++)
-      deleteDCObject(pdwDeleteList[i], false);
+      deleteDCObject(pdwDeleteList[i], false, 0);
 
    unlockDciAccess();
    free(pdwDeleteList);
@@ -414,7 +415,7 @@ void DataCollectionTarget::unbindFromTemplate(UINT32 dwTemplateId, bool removeDC
          }
 
                for(i = 0; i < numDeleted; i++)
-                       deleteDCObject(deleteList[i], false);
+                       deleteDCObject(deleteList[i], false, 0);
 
       unlockDciAccess();
                free(deleteList);
@@ -436,7 +437,7 @@ void DataCollectionTarget::unbindFromTemplate(UINT32 dwTemplateId, bool removeDC
 /**
  * Get list of DCIs to be shown on performance tab
  */
-UINT32 DataCollectionTarget::getPerfTabDCIList(NXCPMessage *pMsg)
+UINT32 DataCollectionTarget::getPerfTabDCIList(NXCPMessage *pMsg, UINT32 userId)
 {
        lockDciAccess(false);
 
@@ -447,7 +448,8 @@ UINT32 DataCollectionTarget::getPerfTabDCIList(NXCPMessage *pMsg)
       if ((object->getPerfTabSettings() != NULL) &&
           object->hasValue() &&
           (object->getStatus() == ITEM_STATUS_ACTIVE) &&
-          object->matchClusterResource())
+          object->matchClusterResource() &&
+          object->hasAccess(userId))
                {
                        pMsg->setField(dwId++, object->getId());
                        pMsg->setField(dwId++, object->getDescription());
@@ -463,7 +465,7 @@ UINT32 DataCollectionTarget::getPerfTabDCIList(NXCPMessage *pMsg)
                // DCI created via instance discovery - send ID of root template item
                // to allow UI to resolve double template case
                // (template -> instance discovery item on node -> actual item on node)
-               DCObject *src = getDCObjectById(object->getTemplateItemId(), false);
+               DCObject *src = getDCObjectById(object->getTemplateItemId(), userId, false);
                pMsg->setField(dwId++, (src != NULL) ? src->getTemplateItemId() : 0);
                dwId += 2;
             }
@@ -488,7 +490,7 @@ UINT32 DataCollectionTarget::getPerfTabDCIList(NXCPMessage *pMsg)
 /**
  * Get threshold violation summary into NXCP message
  */
-UINT32 DataCollectionTarget::getThresholdSummary(NXCPMessage *msg, UINT32 baseId)
+UINT32 DataCollectionTarget::getThresholdSummary(NXCPMessage *msg, UINT32 baseId, UINT32 userId)
 {
        UINT32 varId = baseId;
 
@@ -500,7 +502,7 @@ UINT32 DataCollectionTarget::getThresholdSummary(NXCPMessage *msg, UINT32 baseId
    for(int i = 0; i < m_dcObjects->size(); i++)
        {
                DCObject *object = m_dcObjects->get(i);
-               if (object->hasValue() && (object->getType() == DCO_TYPE_ITEM) && (object->getStatus() == ITEM_STATUS_ACTIVE))
+               if (object->hasValue() && (object->getType() == DCO_TYPE_ITEM) && (object->getStatus() == ITEM_STATUS_ACTIVE) && object->hasAccess(userId))
                {
                        if (((DCItem *)object)->hasActiveThreshold())
                        {
@@ -918,18 +920,18 @@ UINT32 DataCollectionTarget::getStringMapFromScript(const TCHAR *param, StringMa
 /**
  * Get last (current) DCI values for summary table.
  */
-void DataCollectionTarget::getDciValuesSummary(SummaryTable *tableDefinition, Table *tableData)
+void DataCollectionTarget::getDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId)
 {
    if (tableDefinition->isTableDciSource())
-      getTableDciValuesSummary(tableDefinition, tableData);
+      getTableDciValuesSummary(tableDefinition, tableData, userId);
    else
-      getItemDciValuesSummary(tableDefinition, tableData);
+      getItemDciValuesSummary(tableDefinition, tableData, userId);
 }
 
 /**
  * Get last (current) DCI values for summary table using single-value DCIs
  */
-void DataCollectionTarget::getItemDciValuesSummary(SummaryTable *tableDefinition, Table *tableData)
+void DataCollectionTarget::getItemDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId)
 {
    int offset = tableDefinition->isMultiInstance() ? 2 : 1;
    int baseRow = tableData->getNumRows();
@@ -946,7 +948,7 @@ void DataCollectionTarget::getItemDciValuesSummary(SummaryTable *tableDefinition
              ((tc->m_flags & COLUMN_DEFINITION_REGEXP_MATCH) ?
                RegexpMatch(object->getName(), tc->m_dciName, FALSE) :
                !_tcsicmp(object->getName(), tc->m_dciName)
-             ))
+             ) && object->hasAccess(userId))
          {
             int row;
             if (tableDefinition->isMultiInstance())
@@ -1025,7 +1027,7 @@ void DataCollectionTarget::getItemDciValuesSummary(SummaryTable *tableDefinition
 /**
  * Get last (current) DCI values for summary table using table DCIs
  */
-void DataCollectionTarget::getTableDciValuesSummary(SummaryTable *tableDefinition, Table *tableData)
+void DataCollectionTarget::getTableDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId)
 {
    lockDciAccess(false);
    for(int i = 0; i < m_dcObjects->size(); i++)
@@ -1033,7 +1035,8 @@ void DataCollectionTarget::getTableDciValuesSummary(SummaryTable *tableDefinitio
       DCObject *o = m_dcObjects->get(i);
       if ((o->getType() == DCO_TYPE_TABLE) && o->hasValue() &&
            (o->getStatus() == ITEM_STATUS_ACTIVE) &&
-           !_tcsicmp(o->getName(), tableDefinition->getTableDciName()))
+           !_tcsicmp(o->getName(), tableDefinition->getTableDciName()) &&
+           o->hasAccess(userId))
       {
          Table *lastValue = ((DCTable*)o)->getLastValue();
          if (lastValue == NULL)
@@ -1153,10 +1156,10 @@ void DataCollectionTarget::leaveMaintenanceMode()
 /**
  * Update cache size for given data collection item
  */
-void DataCollectionTarget::updateDCItemCacheSize(UINT32 dciId, UINT32 conditionId)
+void DataCollectionTarget::updateDCItemCacheSize(UINT32 dciId, UINT32 userId, UINT32 conditionId)
 {
    lockDciAccess(false);
-   DCObject *dci = getDCObjectById(dciId, false);
+   DCObject *dci = getDCObjectById(dciId, userId, false);
    if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
    {
       static_cast<DCItem*>(dci)->updateCacheSize(conditionId);
@@ -1658,7 +1661,7 @@ bool DataCollectionTarget::updateInstances(DCObject *root, StringMap *instances,
    }
 
    for(int i = 0; i < deleteList.size(); i++)
-      deleteDCObject(deleteList.get(i), false);
+      deleteDCObject(deleteList.get(i), false, 0);
 
    // Create new instances
    if (instances->size() > 0)
index 474d0d7..0f34b69 100644 (file)
@@ -1016,9 +1016,9 @@ void Interface::paeStatusPoll(UINT32 rqId, SNMP_Transport *pTransport, Node *nod
 /**
  * Create NXCP message with object's data
  */
-void Interface::fillMessageInternal(NXCPMessage *pMsg)
+void Interface::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
 
    m_ipAddressList.fillMessage(pMsg, VID_IP_ADDRESS_COUNT, VID_IP_ADDRESS_LIST_BASE);
    pMsg->setField(VID_IF_INDEX, m_index);
index c7500a1..ec35194 100644 (file)
@@ -704,13 +704,13 @@ void MobileDeviceSession::pushData(NXCPMessage *request)
                      DCObject *pItem;
             if (dciId != 0)
             {
-               pItem = device->getDCObjectById(dciId);
+               pItem = device->getDCObjectById(dciId, 0);
             }
             else
             {
                TCHAR name[MAX_PARAM_NAME];
                request->getFieldAsString(varId++, name, MAX_PARAM_NAME);
-               pItem = device->getDCObjectByName(name);
+               pItem = device->getDCObjectByName(name, 0);
             }
 
             if ((pItem != NULL) && (pItem->getType() == DCO_TYPE_ITEM))
index aa1e735..040bc5a 100644 (file)
@@ -180,9 +180,9 @@ bool MobileDevice::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create CSCP message with object's data
  */
-void MobileDevice::fillMessageInternal(NXCPMessage *msg)
+void MobileDevice::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   DataCollectionTarget::fillMessageInternal(msg);
+   DataCollectionTarget::fillMessageInternal(msg, userId);
 
        msg->setField(VID_DEVICE_ID, CHECK_NULL_EX(m_deviceId));
        msg->setField(VID_VENDOR, CHECK_NULL_EX(m_vendor));
index 164091e..f03972d 100644 (file)
@@ -536,9 +536,9 @@ bool NetworkMap::loadFromDatabase(DB_HANDLE hdb, UINT32 dwId)
 /**
  * Fill NXCP message with object's data
  */
-void NetworkMap::fillMessageInternal(NXCPMessage *msg)
+void NetworkMap::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-       NetObj::fillMessageInternal(msg);
+       NetObj::fillMessageInternal(msg, userId);
 
        msg->setField(VID_MAP_TYPE, (WORD)m_mapType);
        msg->setField(VID_LAYOUT, (WORD)m_layout);
index 8b5ec4c..051343e 100644 (file)
@@ -1106,7 +1106,7 @@ static EnumerationCallbackResult SendModuleDataCallback(const TCHAR *key, const
  * Object's properties are locked when this method is called. Method should not do any other locks.
  * Data required other locks should be filled in fillMessageInternalStage2().
  */
-void NetObj::fillMessageInternal(NXCPMessage *pMsg)
+void NetObj::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
    pMsg->setField(VID_OBJECT_CLASS, (WORD)getObjectClass());
    pMsg->setField(VID_OBJECT_ID, m_id);
@@ -1186,19 +1186,19 @@ void NetObj::fillMessageInternal(NXCPMessage *pMsg)
  * used only to fill data where properties lock is not enough (like data
  * collection configuration).
  */
-void NetObj::fillMessageInternalStage2(NXCPMessage *pMsg)
+void NetObj::fillMessageInternalStage2(NXCPMessage *pMsg, UINT32 userId)
 {
 }
 
 /**
  * Fill NXCP message with object's data
  */
-void NetObj::fillMessage(NXCPMessage *msg)
+void NetObj::fillMessage(NXCPMessage *msg, UINT32 userId)
 {
    lockProperties();
-   fillMessageInternal(msg);
+   fillMessageInternal(msg, userId);
    unlockProperties();
-   fillMessageInternalStage2(msg);
+   fillMessageInternalStage2(msg, userId);
 
    lockACL();
    m_accessList->fillMessage(msg);
index 94a1a58..41209fa 100644 (file)
@@ -234,9 +234,9 @@ bool NetworkService::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void NetworkService::fillMessageInternal(NXCPMessage *pMsg)
+void NetworkService::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_SERVICE_TYPE, (WORD)m_serviceType);
    pMsg->setField(VID_IP_ADDRESS, m_ipAddress);
    pMsg->setField(VID_IP_PROTO, m_proto);
index e743db6..2b875f7 100644 (file)
@@ -4719,9 +4719,9 @@ UINT32 Node::getTableForClient(const TCHAR *name, Table **table)
 /**
  * Create NXCP message with object's data
  */
-void Node::fillMessageInternal(NXCPMessage *pMsg)
+void Node::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   DataCollectionTarget::fillMessageInternal(pMsg);
+   DataCollectionTarget::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_IP_ADDRESS, m_ipAddress);
    pMsg->setField(VID_PRIMARY_NAME, m_primaryName);
    pMsg->setField(VID_NODE_TYPE, (INT16)m_type);
index dc5895d..2243a68 100644 (file)
@@ -157,9 +157,9 @@ bool NodeLink::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create CSCP message with object's data
  */
-void NodeLink::fillMessageInternal(NXCPMessage *pMsg)
+void NodeLink::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-       ServiceContainer::fillMessageInternal(pMsg);
+       ServiceContainer::fillMessageInternal(pMsg, userId);
        pMsg->setField(VID_NODE_ID, m_nodeId);
 }
 
index 8482e0e..da043cc 100644 (file)
@@ -140,7 +140,7 @@ bool GetPredictedData(ClientSession *session, const NXCPMessage *request, NXCPMe
    static UINT32 s_rowSize[] = { 8, 8, 16, 16, 516, 16 };
 
    // Find DCI object
-   DCObject *dci = dcTarget->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID));
+   DCObject *dci = dcTarget->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID), session->getUserId());
    if (dci == NULL)
    {
       response->setField(VID_RCC, RCC_INVALID_DCI_ID);
index cff7ac5..e989171 100644 (file)
@@ -119,9 +119,9 @@ bool Rack::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void Rack::fillMessageInternal(NXCPMessage *pMsg)
+void Rack::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   Container::fillMessageInternal(pMsg);
+   Container::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_HEIGHT, (WORD)m_height);
    pMsg->setField(VID_TOP_BOTTOM, (INT16)(m_topBottomNumbering ? 1 : 0));
 }
index fbf200d..3daa246 100644 (file)
@@ -365,9 +365,9 @@ json_t *Sensor::toJson()
    return root;
 }
 
-void Sensor::fillMessageInternal(NXCPMessage *msg)
+void Sensor::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   DataCollectionTarget::fillMessageInternal(msg);
+   DataCollectionTarget::fillMessageInternal(msg, userId);
    msg->setField(VID_SENSOR_FLAGS, m_flags);
        msg->setField(VID_MAC_ADDR, m_macAddress);
    msg->setField(VID_DEVICE_CLASS, m_deviceClass);
index 9b4bfb7..cf5041f 100644 (file)
@@ -2136,7 +2136,7 @@ void ClientSession::sendAllObjects(NXCPMessage *pRequest)
        for(int i = 0; i < objects->size(); i++)
        {
                NetObj *object = objects->get(i);
-      object->fillMessage(&msg);
+      object->fillMessage(&msg, m_dwUserId);
       if (m_dwFlags & CSF_SYNC_OBJECT_COMMENTS)
          object->commentsToMessage(&msg);
       if (!object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
@@ -2199,7 +2199,7 @@ void ClientSession::sendSelectedObjects(NXCPMessage *pRequest)
           (object->getTimeStamp() >= dwTimeStamp) &&
           !object->isHidden() && !object->isSystem())
       {
-         object->fillMessage(&msg);
+         object->fillMessage(&msg, m_dwUserId);
          if (m_dwFlags & CSF_SYNC_OBJECT_COMMENTS)
             object->commentsToMessage(&msg);
          if (!object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_MODIFY))
@@ -2578,7 +2578,7 @@ void ClientSession::sendObjectUpdate(NetObj *object)
    NXCPMessage msg(CMD_OBJECT_UPDATE, 0);
    if (!object->isDeleted())
    {
-      object->fillMessage(&msg);
+      object->fillMessage(&msg, m_dwUserId);
       if (m_dwFlags & CSF_SYNC_OBJECT_COMMENTS)
          object->commentsToMessage(&msg);
    }
@@ -3417,7 +3417,7 @@ void ClientSession::modifyNodeDCI(NXCPMessage *request)
                      break;
                   case CMD_MODIFY_NODE_DCI:
                      dwItemId = request->getFieldAsUInt32(VID_DCI_ID);
-                                                       bSuccess = ((Template *)object)->updateDCObject(dwItemId, request, &dwNumMaps, &pdwMapIndex, &pdwMapId);
+                                                       bSuccess = ((Template *)object)->updateDCObject(dwItemId, request, &dwNumMaps, &pdwMapIndex, &pdwMapId, m_dwUserId);
                      if (bSuccess)
                      {
                         msg.setField(VID_RCC, RCC_SUCCESS);
@@ -3444,7 +3444,7 @@ void ClientSession::modifyNodeDCI(NXCPMessage *request)
                      break;
                   case CMD_DELETE_NODE_DCI:
                      dwItemId = request->getFieldAsUInt32(VID_DCI_ID);
-                     bSuccess = ((Template *)object)->deleteDCObject(dwItemId, true);
+                     bSuccess = ((Template *)object)->deleteDCObject(dwItemId, true, m_dwUserId);
                      msg.setField(VID_RCC, bSuccess ? RCC_SUCCESS : RCC_INVALID_DCI_ID);
                      break;
                }
@@ -3617,7 +3617,7 @@ void ClientSession::clearDCIData(NXCPMessage *request)
          {
                                UINT32 dciId = request->getFieldAsUInt32(VID_DCI_ID);
                                debugPrintf(4, _T("ClearDCIData: request for DCI %d at node %d"), dciId, object->getId());
-            DCObject *dci = ((Template *)object)->getDCObjectById(dciId);
+            DCObject *dci = ((Template *)object)->getDCObjectById(dciId, m_dwUserId);
                                if (dci != NULL)
                                {
                                        msg.setField(VID_RCC, dci->deleteAllData() ? RCC_SUCCESS : RCC_DB_FAILURE);
@@ -3674,7 +3674,7 @@ void ClientSession::forceDCIPoll(NXCPMessage *request)
          {
                                dwItemId = request->getFieldAsUInt32(VID_DCI_ID);
                                debugPrintf(4, _T("ForceDCIPoll: request for DCI %d at node %d"), dwItemId, object->getId());
-            DCObject *dci = ((Template *)object)->getDCObjectById(dwItemId);
+            DCObject *dci = ((Template *)object)->getDCObjectById(dwItemId, m_dwUserId);
                                if (dci != NULL)
                                {
                                   dci->requestForcePoll(this);
@@ -3753,7 +3753,7 @@ void ClientSession::copyDCI(NXCPMessage *pRequest)
                   // Copy items
                   for(i = 0; i < dwNumItems; i++)
                   {
-                     pSrcItem = ((Template *)pSource)->getDCObjectById(pdwItemList[i]);
+                     pSrcItem = ((Template *)pSource)->getDCObjectById(pdwItemList[i], m_dwUserId);
                      if (pSrcItem != NULL)
                      {
                                                                switch(pSrcItem->getType())
@@ -3778,7 +3778,7 @@ void ClientSession::copyDCI(NXCPMessage *pRequest)
                                                                                if (bMove)
                                                                                {
                                                                                        // Delete original item
-                                                                                       if (!((Template *)pSource)->deleteDCObject(pdwItemList[i], TRUE))
+                                                                                       if (!((Template *)pSource)->deleteDCObject(pdwItemList[i], true, m_dwUserId))
                                                                                        {
                                                                                                iErrors++;
                                                                                        }
@@ -3862,7 +3862,7 @@ void ClientSession::sendDCIThresholds(NXCPMessage *request)
       {
                        if (object->isDataCollectionTarget())
                        {
-                               DCObject *dci = ((Template *)object)->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID));
+                               DCObject *dci = ((Template *)object)->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID), m_dwUserId);
                                if ((dci != NULL) && (dci->getType() == DCO_TYPE_ITEM))
                                {
                                        ((DCItem *)dci)->fillMessageWithThresholds(&msg);
@@ -3939,13 +3939,19 @@ bool ClientSession::getCollectedDataFromDB(NXCPMessage *request, NXCPMessage *re
    static UINT32 s_rowSize[] = { 8, 8, 16, 16, 516, 16 };
 
        // Find DCI object
-       DCObject *dci = dcTarget->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID));
+       DCObject *dci = dcTarget->getDCObjectById(request->getFieldAsUInt32(VID_DCI_ID), 0);
        if (dci == NULL)
        {
                response->setField(VID_RCC, RCC_INVALID_DCI_ID);
                return false;
        }
 
+       if(!dci->hasAccess(m_dwUserId))
+       {
+      response->setField(VID_RCC, RCC_ACCESS_DENIED);
+      return false;
+       }
+
        // DCI type in request should match actual DCI type
        if (dci->getType() != dciType)
        {
@@ -4441,7 +4447,8 @@ void ClientSession::getLastValues(NXCPMessage *pRequest)
                ((Template *)object)->getLastValues(&msg,
                   pRequest->getFieldAsBoolean(VID_OBJECT_TOOLTIP_ONLY),
                   pRequest->getFieldAsBoolean(VID_OVERVIEW_ONLY),
-                  pRequest->getFieldAsBoolean(VID_INCLUDE_NOVALUE_OBJECTS)));
+                  pRequest->getFieldAsBoolean(VID_INCLUDE_NOVALUE_OBJECTS),
+                  m_dwUserId));
          }
          else
          {
@@ -4493,7 +4500,7 @@ void ClientSession::getLastValuesByDciId(NXCPMessage *pRequest)
             if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
             {
                UINT32 dciID = pRequest->getFieldAsUInt32(incomingIndex+1);
-               dcoObj = ((DataCollectionTarget *)object)->getDCObjectById(dciID);
+               dcoObj = ((DataCollectionTarget *)object)->getDCObjectById(dciID, m_dwUserId);
                if(dcoObj == NULL)
                   continue;
 
@@ -8642,7 +8649,7 @@ UINT32 ClientSession::resolveDCIName(UINT32 dwNode, UINT32 dwItem, TCHAR *ppszNa
                {
                        if (object->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
                        {
-                               pItem = ((Template *)object)->getDCObjectById(dwItem);
+                               pItem = ((Template *)object)->getDCObjectById(dwItem, m_dwUserId);
                                if (pItem != NULL)
                                {
                _tcsncpy(ppszName, pItem->getDescription(), MAX_DB_STRING);
@@ -9266,12 +9273,12 @@ void ClientSession::pushDCIData(NXCPMessage *pRequest)
                                                DCObject *pItem;
                   if (dwItemId != 0)
                   {
-                     pItem = dcTargetList[i]->getDCObjectById(dwItemId);
+                     pItem = dcTargetList[i]->getDCObjectById(dwItemId, m_dwUserId);
                   }
                   else
                   {
                      pRequest->getFieldAsString(dwId++, szName, 256);
-                     pItem = dcTargetList[i]->getDCObjectByName(szName);
+                     pItem = dcTargetList[i]->getDCObjectByName(szName, m_dwUserId);
                   }
 
                   if ((pItem != NULL) && (pItem->getType() == DCO_TYPE_ITEM))
@@ -9806,7 +9813,7 @@ void ClientSession::SendDCIInfo(NXCPMessage *pRequest)
       {
          if (object->isDataCollectionTarget() || (object->getObjectClass() == OBJECT_TEMPLATE))
          {
-                               DCObject *pItem = ((Template *)object)->getDCObjectById(pRequest->getFieldAsUInt32(VID_DCI_ID));
+                               DCObject *pItem = ((Template *)object)->getDCObjectById(pRequest->getFieldAsUInt32(VID_DCI_ID), m_dwUserId);
                                if ((pItem != NULL) && (pItem->getType() == DCO_TYPE_ITEM))
                                {
                                        msg.setField(VID_TEMPLATE_ID, pItem->getTemplateId());
@@ -9896,7 +9903,7 @@ void ClientSession::sendPerfTabDCIList(NXCPMessage *pRequest)
                {
                        if (object->getObjectClass() == OBJECT_NODE || object->getObjectClass() == OBJECT_CLUSTER || object->getObjectClass() == OBJECT_MOBILEDEVICE || object->getObjectClass() == OBJECT_SENSOR)
                        {
-                               msg.setField(VID_RCC, ((DataCollectionTarget *)object)->getPerfTabDCIList(&msg));
+                               msg.setField(VID_RCC, ((DataCollectionTarget *)object)->getPerfTabDCIList(&msg, m_dwUserId));
                        }
                        else
                        {
@@ -12780,7 +12787,7 @@ void ClientSession::getThresholdSummary(NXCPMessage *request)
                                for(int i = 0; i < targets->size(); i++)
                                {
                                        if (targets->get(i)->checkAccessRights(m_dwUserId, OBJECT_ACCESS_READ))
-                                               varId = targets->get(i)->getThresholdSummary(&msg, varId);
+                                               varId = targets->get(i)->getThresholdSummary(&msg, varId, m_dwUserId);
                                        targets->get(i)->decRefCount();
                                }
                                delete targets;
index f49e924..6be9b95 100644 (file)
@@ -267,9 +267,9 @@ bool SlmCheck::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void SlmCheck::fillMessageInternal(NXCPMessage *pMsg)
+void SlmCheck::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-       NetObj::fillMessageInternal(pMsg);
+       NetObj::fillMessageInternal(pMsg, userId);
        pMsg->setField(VID_SLMCHECK_TYPE, UINT32(m_type));
        pMsg->setField(VID_SCRIPT, CHECK_NULL_EX(m_script));
        pMsg->setField(VID_REASON, m_reason);
index 047fdd1..7cc9f11 100644 (file)
@@ -153,9 +153,9 @@ bool Subnet::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create CSCP message with object's data
  */
-void Subnet::fillMessageInternal(NXCPMessage *pMsg)
+void Subnet::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_IP_ADDRESS, m_ipAddress);
    pMsg->setField(VID_ZONE_UIN, m_zoneUIN);
        pMsg->setField(VID_SYNTHETIC_MASK, (WORD)(m_bSyntheticMask ? 1 : 0));
index 5f3d8ad..3a33260 100644 (file)
@@ -91,9 +91,9 @@ bool ServiceContainer::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void ServiceContainer::fillMessageInternal(NXCPMessage *pMsg)
+void ServiceContainer::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   Container::fillMessageInternal(pMsg);
+   Container::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_UPTIME_DAY, m_uptimeDay);
    pMsg->setField(VID_UPTIME_WEEK, m_uptimeWeek);
    pMsg->setField(VID_UPTIME_MONTH, m_uptimeMonth);
index c83cd32..363b49a 100644 (file)
@@ -383,7 +383,7 @@ void Template::loadItemsFromDB(DB_HANDLE hdb)
               _T("instance,template_item_id,flags,resource_id,")
               _T("proxy_node,base_units,unit_multiplier,custom_units_name,")
                   _T("perftab_settings,system_tag,snmp_port,snmp_raw_value_type,")
-                                 _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name ")
+                                 _T("instd_method,instd_data,instd_filter,samples,comments,guid,npe_name,visibility_rights ")
                                  _T("FROM items WHERE node_id=?"));
        if (hStmt != NULL)
        {
@@ -403,7 +403,7 @@ void Template::loadItemsFromDB(DB_HANDLE hdb)
                   _T("SELECT item_id,template_id,template_item_id,name,")
                                  _T("description,flags,source,snmp_port,polling_interval,retention_time,")
               _T("status,system_tag,resource_id,proxy_node,perftab_settings,")
-              _T("transformation_script,comments,guid,instd_method,instd_data,instd_filter,instance FROM dc_tables WHERE node_id=?"));
+              _T("transformation_script,comments,guid,instd_method,instd_data,instd_filter,instance,visibility_rights FROM dc_tables WHERE node_id=?"));
        if (hStmt != NULL)
        {
                DBBind(hStmt, 1, DB_SQLTYPE_INTEGER, m_id);
@@ -458,7 +458,7 @@ bool Template::addDCObject(DCObject *object, bool alreadyLocked)
 /**
  * Delete data collection object from node
  */
-bool Template::deleteDCObject(UINT32 dcObjectId, bool needLock)
+bool Template::deleteDCObject(UINT32 dcObjectId, bool needLock, UINT32 userId)
 {
    bool success = false;
 
@@ -471,20 +471,25 @@ bool Template::deleteDCObject(UINT32 dcObjectId, bool needLock)
                DCObject *object = m_dcObjects->get(i);
       if (object->getId() == dcObjectId)
       {
-         // Check if it is instance DCI
-         if ((object->getType() == DCO_TYPE_ITEM) && (((DCItem *)object)->getInstanceDiscoveryMethod() != IDM_NONE))
+         if(object->hasAccess(userId))
          {
-            deleteChildDCIs(dcObjectId);
+            // Check if it is instance DCI
+            if ((object->getType() == DCO_TYPE_ITEM) && (((DCItem *)object)->getInstanceDiscoveryMethod() != IDM_NONE))
+            {
+               deleteChildDCIs(dcObjectId);
 
-            // Index may be incorrect at this point
-            if (m_dcObjects->get(i) != object)
-               i = m_dcObjects->indexOf(object);
+               // Index may be incorrect at this point
+               if (m_dcObjects->get(i) != object)
+                  i = m_dcObjects->indexOf(object);
+            }
+            // Destroy item
+            DbgPrintf(7, _T("Template::DeleteDCObject: deleting DCObject %d from object %d"), (int)dcObjectId, (int)m_id);
+            destroyItem(object, i);
+            success = true;
+            DbgPrintf(7, _T("Template::DeleteDCObject: DCO deleted from object %d"), (int)m_id);
          }
-         // Destroy item
-                       DbgPrintf(7, _T("Template::DeleteDCObject: deleting DCObject %d from object %d"), (int)dcObjectId, (int)m_id);
-                       destroyItem(object, i);
-         success = true;
-                       DbgPrintf(7, _T("Template::DeleteDCObject: DCO deleted from object %d"), (int)m_id);
+         else
+            DbgPrintf(3, _T("Template::DeleteDCObject: access denied DCO %d"), (int)m_id);
          break;
       }
        }
@@ -543,7 +548,7 @@ void Template::destroyItem(DCObject *object, int index)
 /**
  * Modify data collection object from NXCP message
  */
-bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId)
+bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userID)
 {
    bool success = false;
 
@@ -555,19 +560,24 @@ bool Template::updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNum
                DCObject *object = m_dcObjects->get(i);
       if (object->getId() == dwItemId)
       {
-                       if (object->getType() == DCO_TYPE_ITEM)
-                       {
-                               ((DCItem *)object)->updateFromMessage(pMsg, pdwNumMaps, ppdwMapIndex, ppdwMapId);
-            if (((DCItem *)object)->getInstanceDiscoveryMethod() != IDM_NONE)
+         if(object->hasAccess(userID))
+         {
+            if (object->getType() == DCO_TYPE_ITEM)
+            {
+               ((DCItem *)object)->updateFromMessage(pMsg, pdwNumMaps, ppdwMapIndex, ppdwMapId);
+               if (((DCItem *)object)->getInstanceDiscoveryMethod() != IDM_NONE)
+               {
+                  updateInstanceDiscoveryItems((DCItem *)object);
+               }
+            }
+            else
             {
-               updateInstanceDiscoveryItems((DCItem *)object);
+               object->updateFromMessage(pMsg);
             }
-                       }
-                       else
-                       {
-                               object->updateFromMessage(pMsg);
-                       }
-                       success = true;
+            success = true;
+         }
+         else
+            DbgPrintf(3, _T("Template::updateDCObject: access denied DCO %d"), (int)m_id);
          break;
       }
        }
@@ -699,9 +709,14 @@ void Template::sendItemsToClient(ClientSession *pSession, UINT32 dwRqId)
    // Walk through items list
    for(int i = 0; i < m_dcObjects->size(); i++)
    {
-               m_dcObjects->get(i)->createMessage(&msg);
-               pSession->sendMessage(&msg);
-               msg.deleteAllFields();
+      if(m_dcObjects->get(i)->hasAccess(pSession->getUserId()))
+      {
+         m_dcObjects->get(i)->createMessage(&msg);
+         pSession->sendMessage(&msg);
+         msg.deleteAllFields();
+      }
+      else
+         DbgPrintf(3, _T("Template::sendItemsToClient: access denied DCO %d"), (int)m_id);
    }
 
    unlockDciAccess();
@@ -712,35 +727,9 @@ void Template::sendItemsToClient(ClientSession *pSession, UINT32 dwRqId)
 }
 
 /**
- * Get DCI's data type
- */
-int Template::getItemType(UINT32 dwItemId)
-{
-   int iType = -1;
-
-   lockDciAccess(false);
-   // Check if that item exists
-   for(int i = 0; i < m_dcObjects->size(); i++)
-       {
-               DCObject *object = m_dcObjects->get(i);
-      if (object->getId() == dwItemId)
-      {
-                       if (object->getType() == DCO_TYPE_ITEM)
-                       {
-                               iType = ((DCItem *)object)->getDataType();
-                       }
-         break;
-      }
-       }
-
-   unlockDciAccess();
-   return iType;
-}
-
-/**
  * Get item by it's id
  */
-DCObject *Template::getDCObjectById(UINT32 itemId, bool lock)
+DCObject *Template::getDCObjectById(UINT32 itemId, UINT32 userID, bool lock)
 {
    DCObject *object = NULL;
 
@@ -752,7 +741,10 @@ DCObject *Template::getDCObjectById(UINT32 itemId, bool lock)
                DCObject *curr = m_dcObjects->get(i);
       if (curr->getId() == itemId)
                {
-                       object = curr;
+         if(curr->hasAccess(userID))
+            object = curr;
+         else
+            DbgPrintf(3, _T("Template::getDCObjectById: access denied DCO %d"), (int)m_id);
          break;
                }
        }
@@ -765,7 +757,7 @@ DCObject *Template::getDCObjectById(UINT32 itemId, bool lock)
 /**
  * Get item by template item id
  */
-DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId)
+DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID)
 {
    DCObject *object = NULL;
 
@@ -776,7 +768,10 @@ DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId)
                DCObject *curr = m_dcObjects->get(i);
       if (curr->getTemplateItemId() == tmplItemId)
                {
-                       object = curr;
+         if(object->hasAccess(userID))
+            object = curr;
+         else
+            DbgPrintf(3, _T("Template::getDCObjectByTemplateId: access denied DCO %d"), (int)m_id);
          break;
                }
        }
@@ -788,7 +783,7 @@ DCObject *Template::getDCObjectByTemplateId(UINT32 tmplItemId)
 /**
  * Get item by it's name (case-insensetive)
  */
-DCObject *Template::getDCObjectByName(const TCHAR *name)
+DCObject *Template::getDCObjectByName(const TCHAR *name, UINT32 userID)
 {
    DCObject *object = NULL;
 
@@ -799,7 +794,10 @@ DCObject *Template::getDCObjectByName(const TCHAR *name)
                DCObject *curr = m_dcObjects->get(i);
       if (!_tcsicmp(curr->getName(), name))
                {
-                       object = curr;
+         if(curr->hasAccess(userID))
+            object = curr;
+         else
+            DbgPrintf(3, _T("Template::getDCObjectByName: access denied DCO %d"), (int)m_id);
          break;
                }
        }
@@ -810,7 +808,7 @@ DCObject *Template::getDCObjectByName(const TCHAR *name)
 /**
  * Get item by it's description (case-insensetive)
  */
-DCObject *Template::getDCObjectByDescription(const TCHAR *description)
+DCObject *Template::getDCObjectByDescription(const TCHAR *description, UINT32 userID)
 {
    DCObject *object = NULL;
 
@@ -821,7 +819,10 @@ DCObject *Template::getDCObjectByDescription(const TCHAR *description)
                DCObject *curr = m_dcObjects->get(i);
       if (!_tcsicmp(curr->getDescription(), description))
                {
-                       object = curr;
+         if(curr->hasAccess(userID))
+            object = curr;
+         else
+            DbgPrintf(3, _T("Template::getDCObjectByDescription: access denied DCO %d"), (int)m_id);
          break;
                }
        }
@@ -832,7 +833,7 @@ DCObject *Template::getDCObjectByDescription(const TCHAR *description)
 /**
  * Get item by GUID
  */
-DCObject *Template::getDCObjectByGUID(const uuid& guid, bool lock)
+DCObject *Template::getDCObjectByGUID(const uuid& guid, UINT32 userID, bool lock)
 {
    DCObject *object = NULL;
 
@@ -845,7 +846,10 @@ DCObject *Template::getDCObjectByGUID(const uuid& guid, bool lock)
       DCObject *curr = m_dcObjects->get(i);
       if (guid.equals(curr->getGuid()))
       {
-         object = curr;
+         if(curr->hasAccess(userID))
+            object = curr;
+         else
+            DbgPrintf(3, _T("Template::getDCObjectByGUID: access denied DCO %d"), (int)m_id);
          break;
       }
    }
@@ -856,20 +860,9 @@ DCObject *Template::getDCObjectByGUID(const uuid& guid, bool lock)
 }
 
 /**
- * Get item by it's index
- */
-DCObject *Template::getDCObjectByIndex(int index)
-{
-   lockDciAccess(false);
-       DCObject *object = m_dcObjects->get(index);
-   unlockDciAccess();
-   return object;
-}
-
-/**
  * Get all DC objects with matching name and description
  */
-NXSL_Value *Template::getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description)
+NXSL_Value *Template::getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description, UINT32 userID)
 {
    NXSL_Array *list = new NXSL_Array();
    lockDciAccess(false);
@@ -877,7 +870,8 @@ NXSL_Value *Template::getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *des
        {
                DCObject *curr = m_dcObjects->get(i);
       if (((name == NULL) || MatchString(name, curr->getName(), false)) &&
-          ((description == NULL) || MatchString(description, curr->getDescription(), false)))
+          ((description == NULL) || MatchString(description, curr->getDescription(), false)) &&
+          curr->hasAccess(userID))
                {
          list->set(list->size(), curr->createNXSLObject());
                }
@@ -897,9 +891,9 @@ void Template::calculateCompoundStatus(BOOL bForcedRecalc)
 /**
  * Create NXCP message with object's data
  */
-void Template::fillMessageInternal(NXCPMessage *pMsg)
+void Template::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_TEMPLATE_VERSION, m_dwVersion);
        pMsg->setField(VID_AUTOBIND_FILTER, CHECK_NULL_EX(m_applyFilterSource));
 }
@@ -1255,7 +1249,7 @@ AutoBindDecision Template::isApplicable(DataCollectionTarget *target)
  * derived from DataCollectionTarget actual values will always be empty strings
  * with data type DCI_DT_NULL.
  */
-UINT32 Template::getLastValues(NXCPMessage *msg, bool objectTooltipOnly, bool overviewOnly, bool includeNoValueObjects)
+UINT32 Template::getLastValues(NXCPMessage *msg, bool objectTooltipOnly, bool overviewOnly, bool includeNoValueObjects, UINT32 userId)
 {
    lockDciAccess(false);
 
@@ -1265,7 +1259,8 @@ UINT32 Template::getLastValues(NXCPMessage *msg, bool objectTooltipOnly, bool ov
                DCObject *object = m_dcObjects->get(i);
                if ((object->hasValue() || includeNoValueObjects) &&
           (!objectTooltipOnly || object->isShowOnObjectTooltip()) &&
-          (!overviewOnly || object->isShowInObjectOverview()))
+          (!overviewOnly || object->isShowInObjectOverview()) &&
+          object->hasAccess(userId))
                {
                        if (object->getType() == DCO_TYPE_ITEM)
                        {
@@ -1323,7 +1318,7 @@ void Template::updateFromImport(ConfigEntry *config)
       {
          ConfigEntry *e = dcis->get(i);
          uuid guid = e->getSubEntryValueAsUUID(_T("guid"));
-         DCObject *curr = !guid.isNull() ? getDCObjectByGUID(guid, false) : NULL;
+         DCObject *curr = !guid.isNull() ? getDCObjectByGUID(guid, 0, false) : NULL;
          if ((curr != NULL) && (curr->getType() == DCO_TYPE_ITEM))
          {
             curr->updateFromImport(e);
@@ -1341,7 +1336,7 @@ void Template::updateFromImport(ConfigEntry *config)
       {
          ConfigEntry *e = dctables->get(i);
          uuid guid = e->getSubEntryValueAsUUID(_T("guid"));
-         DCObject *curr = !guid.isNull() ? getDCObjectByGUID(guid, false) : NULL;
+         DCObject *curr = !guid.isNull() ? getDCObjectByGUID(guid, 0, false) : NULL;
          if ((curr != NULL) && (curr->getType() == DCO_TYPE_TABLE))
          {
             curr->updateFromImport(e);
@@ -1376,7 +1371,7 @@ void Template::updateFromImport(ConfigEntry *config)
    }
 
    for(int i = 0; i < deleteList.size(); i++)
-      deleteDCObject(deleteList.get(i), false);
+      deleteDCObject(deleteList.get(i), false, 0);
 
    unlockDciAccess();
 
index 407dc86..fd11c80 100644 (file)
@@ -223,9 +223,9 @@ Node *VPNConnector::getParentNode()
 /**
  * Create NXCP message with object's data
  */
-void VPNConnector::fillMessageInternal(NXCPMessage *pMsg)
+void VPNConnector::fillMessageInternal(NXCPMessage *pMsg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(pMsg);
+   NetObj::fillMessageInternal(pMsg, userId);
    pMsg->setField(VID_PEER_GATEWAY, m_dwPeerGateway);
    pMsg->setField(VID_NUM_LOCAL_NETS, (UINT32)m_localNetworks->size());
    pMsg->setField(VID_NUM_REMOTE_NETS, (UINT32)m_remoteNetworks->size());
index 4f2aead..40b5759 100644 (file)
@@ -174,9 +174,9 @@ bool Zone::deleteFromDatabase(DB_HANDLE hdb)
 /**
  * Create NXCP message with object's data
  */
-void Zone::fillMessageInternal(NXCPMessage *msg)
+void Zone::fillMessageInternal(NXCPMessage *msg, UINT32 userId)
 {
-   NetObj::fillMessageInternal(msg);
+   NetObj::fillMessageInternal(msg, userId);
    msg->setField(VID_ZONE_UIN, m_uin);
    msg->setField(VID_ZONE_PROXY, m_proxyNodeId);
    m_snmpPorts.fillMessage(msg, VID_ZONE_SNMP_PORT_LIST_BASE, VID_ZONE_SNMP_PORT_COUNT);
index fa00aa4..81cafd8 100644 (file)
@@ -217,6 +217,7 @@ protected:
    TCHAR *m_instanceFilterSource;
    NXSL_Program *m_instanceFilter;
    TCHAR m_instance[MAX_DB_STRING];
+   IntegerArray<UINT32> *m_visibilityRights;
 
    void lock() { MutexLock(m_hMutex); }
    bool tryLock() { return MutexTryLock(m_hMutex); }
@@ -334,6 +335,7 @@ public:
    const TCHAR *getInstance() const { return m_instance; }
    void expandInstance();
    bool hasValue();
+   bool hasAccess(UINT32 userId);
 };
 
 /**
index 7835638..eeb6ec7 100644 (file)
@@ -561,8 +561,8 @@ protected:
    virtual void prepareForDeletion();
    virtual void onObjectDelete(UINT32 dwObjectId);
 
-   virtual void fillMessageInternal(NXCPMessage *msg);
-   virtual void fillMessageInternalStage2(NXCPMessage *msg);
+   virtual void fillMessageInternal(NXCPMessage *msg, UINT32 userId);
+   virtual void fillMessageInternalStage2(NXCPMessage *msg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *msg);
 
    void addLocationToHistory();
@@ -643,7 +643,7 @@ public:
    virtual void enterMaintenanceMode();
    virtual void leaveMaintenanceMode();
 
-   void fillMessage(NXCPMessage *msg);
+   void fillMessage(NXCPMessage *msg, UINT32 userId);
    UINT32 modifyFromMessage(NXCPMessage *msg);
 
        virtual void postModify();
@@ -756,7 +756,7 @@ protected:
 
    virtual void prepareForDeletion();
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    virtual void onDataCollectionChange();
@@ -792,17 +792,15 @@ public:
 
    int getItemCount() { return m_dcObjects->size(); }
    bool addDCObject(DCObject *object, bool alreadyLocked = false);
-   bool updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId);
-   bool deleteDCObject(UINT32 dcObjectId, bool needLock);
+   bool updateDCObject(UINT32 dwItemId, NXCPMessage *pMsg, UINT32 *pdwNumMaps, UINT32 **ppdwMapIndex, UINT32 **ppdwMapId, UINT32 userID);
+   bool deleteDCObject(UINT32 dcObjectId, bool needLock, UINT32 userID);
    bool setItemStatus(UINT32 dwNumItems, UINT32 *pdwItemList, int iStatus);
-   int getItemType(UINT32 dwItemId);
-   DCObject *getDCObjectById(UINT32 itemId, bool lock = true);
-   DCObject *getDCObjectByGUID(const uuid& guid, bool lock = true);
-   DCObject *getDCObjectByTemplateId(UINT32 tmplItemId);
-   DCObject *getDCObjectByIndex(int index);
-   DCObject *getDCObjectByName(const TCHAR *name);
-   DCObject *getDCObjectByDescription(const TCHAR *description);
-   NXSL_Value *getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description);
+   DCObject *getDCObjectById(UINT32 itemId, UINT32 userID, bool lock = true);
+   DCObject *getDCObjectByGUID(const uuid& guid, UINT32 userID, bool lock = true);
+   DCObject *getDCObjectByTemplateId(UINT32 tmplItemId, UINT32 userID);
+   DCObject *getDCObjectByName(const TCHAR *name, UINT32 userID);
+   DCObject *getDCObjectByDescription(const TCHAR *description, UINT32 userID);
+   NXSL_Value *getAllDCObjectsForNXSL(const TCHAR *name, const TCHAR *description, UINT32 userID);
    bool lockDCIList(int sessionId, const TCHAR *pszNewOwner, TCHAR *pszCurrOwner);
    bool unlockDCIList(int sessionId);
    void setDCIModificationFlag() { m_dciListModified = true; }
@@ -825,7 +823,7 @@ public:
        bool enumDCObjects(bool (* pfCallback)(DCObject *, UINT32, void *), void *pArg);
        void associateItems();
 
-   UINT32 getLastValues(NXCPMessage *msg, bool objectTooltipOnly, bool overviewOnly, bool includeNoValueObjects);
+   UINT32 getLastValues(NXCPMessage *msg, bool objectTooltipOnly, bool overviewOnly, bool includeNoValueObjects, UINT32 userId);
 };
 
 class Cluster;
@@ -874,7 +872,7 @@ protected:
 protected:
    virtual void onObjectDelete(UINT32 dwObjectId);
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    void setExpectedStateInternal(int state);
@@ -987,7 +985,7 @@ protected:
 
    virtual void onObjectDelete(UINT32 dwObjectId);
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -1020,7 +1018,7 @@ protected:
    ObjectArray<InetAddress> *m_localNetworks;
    ObjectArray<InetAddress> *m_remoteNetworks;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    Node *getParentNode();
@@ -1072,8 +1070,8 @@ protected:
    time_t m_lastInstancePoll;
    MUTEX m_hPollerMutex;
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
-       virtual void fillMessageInternalStage2(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
+       virtual void fillMessageInternalStage2(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
        virtual bool isDataCollectionDisabled();
@@ -1097,8 +1095,8 @@ protected:
    void applyUserTemplates();
    void updateContainerMembership();
 
-   void getItemDciValuesSummary(SummaryTable *tableDefinition, Table *tableData);
-   void getTableDciValuesSummary(SummaryTable *tableDefinition, Table *tableData);
+   void getItemDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId);
+   void getTableDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId);
 
    void addProxyDataCollectionElement(ProxyInfo *info, const DCObject *dco);
    void addProxySnmpTarget(ProxyInfo *info, const Node *node);
@@ -1130,9 +1128,9 @@ public:
    UINT32 getStringMapFromScript(const TCHAR *param, StringMap **map, DataCollectionTarget *targetObject);
 
    UINT32 getTableLastValues(UINT32 dciId, NXCPMessage *msg);
-       UINT32 getThresholdSummary(NXCPMessage *msg, UINT32 baseId);
-       UINT32 getPerfTabDCIList(NXCPMessage *pMsg);
-   void getDciValuesSummary(SummaryTable *tableDefinition, Table *tableData);
+       UINT32 getThresholdSummary(NXCPMessage *msg, UINT32 baseId, UINT32 userId);
+       UINT32 getPerfTabDCIList(NXCPMessage *pMsg, UINT32 userId);
+   void getDciValuesSummary(SummaryTable *tableDefinition, Table *tableData, UINT32 userId);
 
    void updateDciCache();
    void updateDCItemCacheSize(UINT32 dciId, UINT32 conditionId = 0);
@@ -1280,7 +1278,7 @@ protected:
        LONG m_batteryLevel;
    InetAddress m_ipAddress;
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -1336,7 +1334,7 @@ protected:
    AccessPointState m_apState;
    AccessPointState m_prevState;
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    virtual void updatePingData();
@@ -1388,7 +1386,7 @@ protected:
        CLUSTER_RESOURCE *m_pResourceList;
        UINT32 m_zoneUIN;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    virtual void onDataCollectionChange();
@@ -1442,7 +1440,7 @@ protected:
    UINT32 m_rackId;
    uuid m_rackImage;
 
-   virtual void fillMessageInternal(NXCPMessage *msg);
+   virtual void fillMessageInternal(NXCPMessage *msg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *request);
 
    virtual void onDataCollectionChange();
@@ -1519,7 +1517,7 @@ protected:
    UINT32 m_frequency; //*10 from origin number // 0 when no value
    UINT32 m_proxyNodeId;
 
-       virtual void fillMessageInternal(NXCPMessage *msg);
+       virtual void fillMessageInternal(NXCPMessage *msg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *request);
 
    virtual void statusPoll(PollerInfo *poller, ClientSession *session, UINT32 rqId);
@@ -1763,7 +1761,7 @@ protected:
    virtual void prepareForDeletion();
    virtual void onObjectDelete(UINT32 dwObjectId);
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    virtual void updatePingData();
@@ -2138,7 +2136,7 @@ protected:
 
    virtual void prepareForDeletion();
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
 
    void buildIPTopologyInternal(NetworkMapObjectList &topology, int nDepth, UINT32 seedNode, bool includeEndNodes);
 
@@ -2227,7 +2225,7 @@ protected:
        NXSL_Program *m_bindFilter;
        TCHAR *m_bindFilterSource;
 
-   virtual void fillMessageInternal(NXCPMessage *msg);
+   virtual void fillMessageInternal(NXCPMessage *msg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *request);
 
    void setAutoBindFilterInternal(const TCHAR *script);
@@ -2288,7 +2286,7 @@ protected:
        int m_height;   // Rack height in units
        bool m_topBottomNumbering;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2318,7 +2316,7 @@ protected:
        InetAddressIndex *m_idxSubnetByAddr;
        StringList m_snmpPorts;
 
-   virtual void fillMessageInternal(NXCPMessage *msg);
+   virtual void fillMessageInternal(NXCPMessage *msg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *request);
 
 public:
@@ -2407,7 +2405,7 @@ protected:
    time_t m_lastPoll;
    bool m_queuedForPolling;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2448,7 +2446,7 @@ protected:
 
        bool savePolicyCommonProperties(DB_HANDLE hdb);
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2478,7 +2476,7 @@ class NXCORE_EXPORTABLE AgentPolicyConfig : public AgentPolicy
 protected:
        TCHAR *m_fileContent;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2506,7 +2504,7 @@ class NXCORE_EXPORTABLE AgentPolicyLogParser : public AgentPolicy
  protected:
    TCHAR *m_fileContent;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
  public:
    AgentPolicyLogParser();
@@ -2607,7 +2605,7 @@ protected:
        TCHAR *m_filterSource;
        NXSL_VM *m_filter;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
        void updateObjects(NetworkMapObjectList *objects);
@@ -2686,7 +2684,7 @@ protected:
        UINT32 m_options;
        ObjectArray<DashboardElement> *m_elements;
 
-   virtual void fillMessageInternal(NXCPMessage *pMsg);
+   virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
    virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2741,7 +2739,7 @@ protected:
 
    virtual void onObjectDelete(UINT32 objectId);
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
        virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
    void setScript(const TCHAR *script);
@@ -2801,7 +2799,7 @@ protected:
        static INT32 getSecondsInPeriod(Period period) { return period == MONTH ? getSecondsInMonth() : (period == WEEK ? (3600 * 24 * 7) : (3600 * 24)); }
        static INT32 getSecondsSinceBeginningOf(Period period, time_t *beginTime = NULL);
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
        virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
        void initServiceContainer();
@@ -2859,7 +2857,7 @@ protected:
 
    virtual void prepareForDeletion();
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
        virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
 public:
@@ -2891,7 +2889,7 @@ protected:
 
    virtual void onObjectDelete(UINT32 dwObjectId);
 
-       virtual void fillMessageInternal(NXCPMessage *pMsg);
+       virtual void fillMessageInternal(NXCPMessage *pMsg, UINT32 userId);
        virtual UINT32 modifyFromMessageInternal(NXCPMessage *pRequest);
 
        void applyTemplate(SlmCheck *tmpl);
index 2210fb0..1061953 100644 (file)
 #include "nxdbmgr.h"
 
 /**
- * Upgrade from 22.2 to 30.0
+ * Upgrade from 22.3 to 30.0
  */
-static bool H_UpgradeFromV2()
+static bool H_UpgradeFromV3()
 {
    CHK_EXEC(SetMajorSchemaVersion(30, 0));
    return true;
 }
 
 /**
+ * Upgrade from 22.2 to 22.3
+ */
+static bool H_UpgradeFromV2()
+{
+   static const TCHAR *batch =
+            _T("ALTER TABLE dc_tables ADD visibility_rights varchar(2000)\n")
+            _T("ALTER TABLE items ADD visibility_rights varchar(2000)\n")
+            _T("<END>");
+   CHK_EXEC(SQLBatch(batch));
+   CHK_EXEC(SetMinorSchemaVersion(3));
+   return true;
+}
+
+/**
  * Upgrade from 22.1 to 22.2
  */
 static bool H_UpgradeFromV1()
@@ -68,7 +82,8 @@ static struct
    bool (* upgradeProc)();
 } s_dbUpgradeMap[] =
 {
-   { 2, 30, 0, H_UpgradeFromV2 },
+   { 3, 30, 0, H_UpgradeFromV3 },
+   { 2, 22, 3, H_UpgradeFromV2 },
    { 1, 22, 2, H_UpgradeFromV1 },
    { 0, 22, 1, H_UpgradeFromV0 },
    { 0, 0, 0, NULL }
index cd2a8d2..d3e1f35 100644 (file)
 #include "nxdbmgr.h"
 
 /**
+ * Upgrade from 30.11 to 30.12
+ */
+static bool H_UpgradeFromV11()
+{
+   if (GetSchemaLevelForMajorVersion(22) < 3)
+   {
+      static const TCHAR *batch =
+               _T("ALTER TABLE dc_tables ADD visibility_rights varchar(2000)\n")
+               _T("ALTER TABLE items ADD visibility_rights varchar(2000)\n")
+               _T("<END>");
+      CHK_EXEC(SQLBatch(batch));
+      CHK_EXEC(SetSchemaLevelForMajorVersion(22, 3));
+      CHK_EXEC(SetMinorSchemaVersion(12));
+   }
+   return true;
+}
+
+/**
  * Upgrade from 30.10 to 30.11
  */
 static bool H_UpgradeFromV10()
@@ -542,6 +560,7 @@ static struct
    bool (* upgradeProc)();
 } s_dbUpgradeMap[] =
 {
+   { 11, 30, 12, H_UpgradeFromV11 },
    { 10, 30, 11, H_UpgradeFromV10 },
    { 9, 30, 10, H_UpgradeFromV9 },
    { 8, 30, 9, H_UpgradeFromV8 },
index c33d38b..13e7fa9 100644 (file)
@@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.rap.ui;bundle-version="2.3.1",
  org.netxms.ui.eclipse.snmp;bundle-version="2.0.0",
  org.netxms.ui.eclipse.nxsl;bundle-version="2.0.7",
  org.netxms.ui.eclipse.charts;bundle-version="2.0.5",
- org.netxms.ui.eclipse.objectview;bundle-version="2.0.7"
+ org.netxms.ui.eclipse.objectview;bundle-version="2.0.7",
+ org.netxms.ui.eclipse.usermanager;bundle-version="2.0.8"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.netxms.ui.eclipse.datacollection.actions,
index fbe16a6..dd36b9b 100644 (file)
               </instanceof>
            </enabledWhen>
         </page>
+        <page
+              class="org.netxms.ui.eclipse.datacollection.propertypages.VisibilityControl"
+              id="org.netxms.ui.eclipse.datacollection.propertypages.InstanceDiscovery#50"
+              name="Visibility">
+           <enabledWhen>
+              <instanceof
+                    value="org.netxms.client.datacollection.DataCollectionObject">
+              </instanceof>
+           </enabledWhen>
+        </page>
    </extension>
 
   <extension
diff --git a/webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java b/webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/VisibilityControl.java
new file mode 100644 (file)
index 0000000..2991190
--- /dev/null
@@ -0,0 +1,244 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2011 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.ui.eclipse.datacollection.propertypages;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.netxms.client.NXCSession;
+import org.netxms.client.datacollection.DataCollectionObject;
+import org.netxms.client.users.AbstractUserObject;
+import org.netxms.client.users.User;
+import org.netxms.ui.eclipse.datacollection.api.DataCollectionObjectEditor;
+import org.netxms.ui.eclipse.datacollection.propertypages.helpers.DCIPropertyPageDialog;
+import org.netxms.ui.eclipse.datacollection.propertypages.helpers.VisibilityUserListLabelProvider;
+import org.netxms.ui.eclipse.shared.ConsoleSharedData;
+import org.netxms.ui.eclipse.tools.ObjectLabelComparator;
+import org.netxms.ui.eclipse.tools.WidgetHelper;
+import org.netxms.ui.eclipse.usermanager.dialogs.SelectUserDialog;
+
+/**
+ * "Access Control" property page
+ */
+public class VisibilityControl extends DCIPropertyPageDialog
+{
+   private DataCollectionObjectEditor editor;
+   private DataCollectionObject dco;
+       private Set<AbstractUserObject> acl = new HashSet<AbstractUserObject>();
+       private TableViewer viewer;
+       private Button buttonAdd;
+       private Button buttonRemove;
+       private static final String info[] = {"Inherited from object access rights"};
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#createControl(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       public void createControl(Composite parent)
+       {
+               noDefaultAndApplyButton();
+               super.createControl(parent);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+        */
+       @Override
+       protected Control createContents(Composite parent)
+       {
+      editor = (DataCollectionObjectEditor)getElement().getAdapter(DataCollectionObjectEditor.class);
+      dco = editor.getObject();      
+
+      // Initiate loading of user manager plugin if it was not loaded before
+      Platform.getAdapterManager().loadAdapter(new User(""), "org.eclipse.ui.model.IWorkbenchAdapter"); //$NON-NLS-1$ //$NON-NLS-2$
+               
+               // Build internal copy of access list
+               final NXCSession session = (NXCSession)ConsoleSharedData.getSession();
+               for(Long uid : dco.getAccessList())
+               {
+                       AbstractUserObject o = session.findUserDBObjectById(uid);
+                       if (o != null)
+                               acl.add(o);
+               }
+               
+               Composite dialogArea = new Composite(parent, SWT.NONE);
+               
+               GridLayout layout = new GridLayout();
+               layout.verticalSpacing = WidgetHelper.INNER_SPACING;
+               layout.marginWidth = 0;
+               layout.marginHeight = 0;
+               dialogArea.setLayout(layout);
+               
+               Label label = new Label(dialogArea, SWT.NONE);
+               label.setText("Visible to:");
+               
+               viewer = new TableViewer(dialogArea, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
+               viewer.setContentProvider(new ArrayContentProvider());
+               viewer.setLabelProvider(new VisibilityUserListLabelProvider());
+               viewer.setComparator(new ObjectLabelComparator((ILabelProvider)viewer.getLabelProvider()));
+               viewer.getTable().setSortDirection(SWT.UP);
+               GridData gd = new GridData();
+               gd.horizontalAlignment = SWT.FILL;
+               gd.verticalAlignment = SWT.FILL;
+               gd.grabExcessHorizontalSpace = true;
+               gd.grabExcessVerticalSpace = true;
+               gd.heightHint = 300;
+               viewer.getTable().setLayoutData(gd);
+               viewer.setInput(acl.toArray());
+               updateInfoNote();
+               
+      Composite buttons = new Composite(dialogArea, SWT.NONE);
+      RowLayout buttonLayout = new RowLayout();
+      buttonLayout.type = SWT.HORIZONTAL;
+      buttonLayout.pack = false;
+      buttonLayout.marginWidth = 0;
+      buttons.setLayout(buttonLayout);
+      gd = new GridData();
+      gd.horizontalAlignment = SWT.RIGHT;
+      gd.verticalIndent = WidgetHelper.OUTER_SPACING - WidgetHelper.INNER_SPACING;
+      buttons.setLayoutData(gd);
+
+      buttonAdd = new Button(buttons, SWT.PUSH);
+      buttonAdd.setText("Add");
+      buttonAdd.addSelectionListener(new SelectionListener() {
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               addUser();
+                       }
+      });
+      RowData rd = new RowData();
+      rd.width = WidgetHelper.BUTTON_WIDTH_HINT;
+      buttonAdd.setLayoutData(rd);
+               
+      buttonRemove = new Button(buttons, SWT.PUSH);
+      buttonRemove.setText("Remove");
+      buttonRemove.addSelectionListener(new SelectionListener() {
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               removeUsers();
+                       }
+      });
+      rd = new RowData();
+      rd.width = WidgetHelper.BUTTON_WIDTH_HINT;
+      buttonRemove.setLayoutData(rd);
+               
+               return dialogArea;
+       }
+       
+       /**
+        * Adds info element to the list if empty
+        */
+       public void updateInfoNote()
+       {
+      if(acl.size() == 0)
+      {
+         viewer.setInput(info);
+      }
+       }
+       
+       /**
+        * Add users to ACL
+        */
+       public void addUser()
+       {
+               SelectUserDialog dlg = new SelectUserDialog(getShell(), AbstractUserObject.class);
+               if (dlg.open() == Window.OK)
+               {
+                       for(AbstractUserObject o : dlg.getSelection())
+                               acl.add(o);
+                       viewer.setInput(acl.toArray());
+               }
+       }
+       
+       /**
+        * Remove users from ACL
+        */
+       public void removeUsers()
+       {
+               IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+               for(Object o : selection.toList())
+                       acl.remove(o);
+               viewer.setInput(acl.toArray());
+               updateInfoNote();
+       }
+       
+       /**
+        * Apply changes
+        * 
+        * @param isApply true if update operation caused by "Apply" button
+        */
+       protected void applyChanges(final boolean isApply)
+       {
+               List<Long> list = new ArrayList<Long>(acl.size());
+               for(AbstractUserObject o : acl)
+                       list.add(o.getId());
+               dco.setAccessList(list);
+       }
+       
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#performApply()
+        */
+       @Override
+       protected void performApply()
+       {
+               applyChanges(true);
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.jface.preference.PreferencePage#performOk()
+        */
+       @Override
+       public boolean performOk()
+       {
+               applyChanges(false);
+               return true;
+       }
+}
diff --git a/webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java b/webui/webapp/DataCollection/src/org/netxms/ui/eclipse/datacollection/propertypages/helpers/VisibilityUserListLabelProvider.java
new file mode 100644 (file)
index 0000000..e619500
--- /dev/null
@@ -0,0 +1,55 @@
+package org.netxms.ui.eclipse.datacollection.propertypages.helpers;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+/**
+ * Label provider for visibility table. 
+ * Uses default workbench label provider for user object and 
+ * implements own for String like with warning. 
+ */
+public class VisibilityUserListLabelProvider extends LabelProvider
+{
+   private WorkbenchLabelProvider workbenchLabelProvider;
+   
+   /**
+    * Default constructor
+    */
+   public VisibilityUserListLabelProvider()
+   {
+      workbenchLabelProvider = new WorkbenchLabelProvider();
+   }    
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+    */
+   @Override
+   public Image getImage(Object element)
+   {
+      if(element instanceof String)
+         return null;
+      return workbenchLabelProvider.getImage(element);
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+    */
+   @Override
+   public String getText(Object element)
+   {
+      if(element instanceof String)
+         return (String)element;
+      return workbenchLabelProvider.getText(element);
+   }
+
+   /* (non-Javadoc)
+    * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose()
+    */
+   @Override
+   public void dispose()
+   {
+      workbenchLabelProvider.dispose();
+      super.dispose();
+   }
+}