Browse Source

test accesslevel bit for reading

Julius Pfrommer 7 years ago
parent
commit
645e4ef5d4

+ 9 - 1
CHANGELOG

@@ -1,10 +1,18 @@
 The changelog tracks changes to the public API.
 Internal refactorings and bug fixes are not reported here.
 
+2017-06-16 jpfr <julius.pfrommer at web.de>
+
+    * Require the AccessLevel bit UA_ACCESSLEVELMASK_READ for reading
+
+      Set the bit by default when adding nodes for a smooth transition to
+      the new API. This will change at a later point with an additional
+      node settings argument for the AddNodes methods.
+
 2017-05-03 pro <profanter at fortiss.org>
 
     * Array dimensions are UInt32 also for the highlevel client read service
-	
+
 2017-04-16 jpfr <julius.pfrommer at web.de>
 
     * Refactor UA_parseEndpointUrl to work with UA_String

+ 7 - 1
src/server/ua_services_attribute.c

@@ -795,11 +795,17 @@ void Service_Read_single(UA_Server *server, UA_Session *session,
         forceVariantSetScalar(&v->value, &((const UA_ViewNode*)node)->eventNotifier,
                               &UA_TYPES[UA_TYPES_BYTE]);
         break;
-    case UA_ATTRIBUTEID_VALUE:
+    case UA_ATTRIBUTEID_VALUE: {
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
+        UA_Byte userAccessLevel = getUserAccessLevel(server, session, (const UA_VariableNode*)node);
+        if(!(userAccessLevel & (UA_ACCESSLEVELMASK_READ))) {
+            retval = UA_STATUSCODE_BADUSERACCESSDENIED;
+            break;
+        }
         retval = readValueAttributeComplete(server, (const UA_VariableNode*)node,
                                             timestamps, &id->indexRange, v);
         break;
+    }
     case UA_ATTRIBUTEID_DATATYPE:
         CHECK_NODECLASS(UA_NODECLASS_VARIABLE | UA_NODECLASS_VARIABLETYPE);
         forceVariantSetScalar(&v->value, &((const UA_VariableTypeNode*)node)->dataType,

+ 10 - 1
src/server/ua_services_nodemanagement.c

@@ -834,9 +834,9 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
         return retval;
     }
     
-    /* Type check node */
     if(node->nodeClass == UA_NODECLASS_VARIABLE ||
        node->nodeClass == UA_NODECLASS_VARIABLETYPE) {
+        /* Type check node */
         retval = typeCheckVariableNode(server, session, (const UA_VariableNode*)node, typeDefinition);
         if(retval != UA_STATUSCODE_GOOD) {
             UA_LOG_INFO_SESSION(server->config.logger, session,
@@ -845,6 +845,15 @@ Service_AddNode_finish(UA_Server *server, UA_Session *session, const UA_NodeId *
             deleteNode(server, &adminSession, nodeId, true);
             return retval;
         }
+
+        /* Set AccessLevel to readable */
+        const UA_VariableNode *vn = (const UA_VariableNode*)node;
+        if(!(vn->accessLevel & (UA_ACCESSLEVELMASK_READ))) {
+            UA_LOG_INFO_SESSION(server->config.logger, session,
+                                "AddNodes: Set the AccessLevel to readable by default");
+            UA_Byte readable = vn->accessLevel | (UA_ACCESSLEVELMASK_READ);
+            UA_Server_writeAccessLevel(server, vn->nodeId, readable);
+        }
     }
 
     /* Add parent reference */

+ 2 - 2
tests/check_services_attributes.c

@@ -472,7 +472,7 @@ START_TEST(ReadSingleAttributeAccessLevelWithoutTimestamp) {
 
     ck_assert_int_eq(0, resp.value.arrayLength);
     ck_assert_ptr_eq(&UA_TYPES[UA_TYPES_BYTE], resp.value.type);
-    ck_assert_int_eq(*(UA_Byte*)resp.value.data, 0);
+    ck_assert_int_eq(*(UA_Byte*)resp.value.data, UA_ACCESSLEVELMASK_READ); // set by default
     UA_DataValue_deleteMembers(&resp);
     UA_Server_delete(server);
 } END_TEST
@@ -1034,4 +1034,4 @@ int main(void) {
 
 #ifdef __clang__
 #pragma clang diagnostic pop
-#endif
+#endif