private ServiceResult OnApproveLock( ISystemContext context, MethodState method, NodeId objectId, IList <object> inputArguments, IList <object> outputArguments) { DsatsDemo.LockConditionState node = (DsatsDemo.LockConditionState)FindPredefinedNode(objectId, typeof(DsatsDemo.LockConditionState)); if (!node.EnabledState.Id.Value) { return(StatusCodes.BadConditionDisabled); } if (node.LockState.CurrentState.Id.Value != new NodeId(DsatsDemo.Objects.LockStateMachineType_WaitingForApproval, NamespaceIndex)) { return(StatusCodes.BadConditionNotShelved); } // only admins can approve locks. if (!CheckAdminAccess(context)) { return(StatusCodes.BadUserAccessDenied); } // grant the lock. GrantLockToSession(context, node.SessionId.Value, objectId); node.SetLock(context); node.ReportEvent(context, node); node.ClearChangeMasks(context, true); return(ServiceResult.Good); }
void LoadDataSourceLocks(ISystemContext context, DsatsDemo.DataSource.DataSource datasource) { if (datasource == null || datasource.Lock == null) { return; } foreach (DsatsDemo.DataSource.LockType source in datasource.Lock) { DsatsDemo.LockConditionState node = datasource.ReadLock(context, source); node.Request.OnCallMethod2 = OnRequestLock; node.Release.OnCallMethod2 = OnReleaseLock; node.Approve.OnCallMethod2 = OnApproveLock; node.LockStateAsString.OnWriteValue = OnChangeLockByWrite; if (source.Permission != null) { foreach (DsatsDemo.DataSource.CertificatePermissionType permission in source.Permission) { node.SetPermission(permission.Thumbprint); } } node.AddNotifier(context, Opc.Ua.ReferenceTypeIds.HasEventSource, true, m_rig.Locks); m_rig.Locks.AddNotifier(context, Opc.Ua.ReferenceTypeIds.HasEventSource, false, node); AddPredefinedNode(context, node); } }
/// <summary> /// Called when a session is closed. /// </summary> public override void SessionClosing(OperationContext context, NodeId sessionId, bool deleteSubscriptions) { lock (Lock) { List <NodeId> locks = null; if (!m_sessionLocks.TryGetValue(sessionId, out locks)) { return; } m_sessionLocks.Remove(sessionId); for (int ii = 0; ii < locks.Count; ii++) { DsatsDemo.LockConditionState node = (DsatsDemo.LockConditionState)FindPredefinedNode(locks[ii], typeof(DsatsDemo.LockConditionState)); if (node != null) { node.SessionId.Value = null; node.ClientUserId.Value = null; node.SubjectName.Value = null; node.Unlock(SystemContext); node.ReportEvent(SystemContext, node); } } } }
private ServiceResult OnRequestLock( ISystemContext context, MethodState method, NodeId objectId, IList <object> inputArguments, IList <object> outputArguments) { DsatsDemo.LockConditionState node = (DsatsDemo.LockConditionState)FindPredefinedNode(objectId, typeof(DsatsDemo.LockConditionState)); if (!node.EnabledState.Id.Value) { return(StatusCodes.BadConditionDisabled); } if (node.LockState.CurrentState.Id.Value != new NodeId(DsatsDemo.Objects.LockStateMachineType_Unlocked, NamespaceIndex)) { return(StatusCodes.BadConditionAlreadyShelved); } node.SessionId.Value = context.SessionId; node.ClientUserId.Value = null; node.SubjectName.Value = null; // get the current user name. if (context.UserIdentity != null) { node.ClientUserId.Value = context.UserIdentity.DisplayName; } X509Certificate2 certificate = null; // get the client certificate subject name. ServerSystemContext systemContext = context as ServerSystemContext; if (systemContext != null && systemContext.OperationContext != null && systemContext.OperationContext.Session != null && systemContext.OperationContext.Session.ClientCertificate != null) { certificate = systemContext.OperationContext.Session.ClientCertificate; node.SubjectName.Value = certificate.Subject; } node.RequestLock(context); // admins get locks immediately. if (CheckAdminAccess(context) || (certificate != null && node.HasPermission(certificate))) { GrantLockToSession(context, node.SessionId.Value, objectId); node.SetLock(context); } node.ReportEvent(context, node); node.ClearChangeMasks(context, true); return(ServiceResult.Good); }
public ServiceResult OnChangeLockByWrite( ISystemContext context, NodeState node, NumericRange indexRange, QualifiedName dataEncoding, ref object value, ref StatusCode statusCode, ref DateTime timestamp) { DsatsDemo.LockConditionState condition = null; BaseInstanceState instance = node as BaseInstanceState; if (instance.Parent != null) { condition = instance.Parent as DsatsDemo.LockConditionState; } if (condition == null) { return(StatusCodes.BadNotWritable); } string lockState = value as string; if (lockState == null) { return(StatusCodes.BadTypeMismatch); } if (lockState == "Locked") { ServiceResult result = OnRequestLock(context, condition.Request, condition.NodeId, new object[0], new object[0]); value = condition.LockStateAsString.Value; return(result); } else if (lockState == "Unlocked") { ServiceResult result = OnReleaseLock(context, condition.Request, condition.NodeId, new object[0], new object[0]); value = condition.LockStateAsString.Value; return(result); } return(StatusCodes.BadTypeMismatch); }
private ServiceResult OnReleaseLock( ISystemContext context, MethodState method, NodeId objectId, IList <object> inputArguments, IList <object> outputArguments) { DsatsDemo.LockConditionState node = (DsatsDemo.LockConditionState)FindPredefinedNode(objectId, typeof(DsatsDemo.LockConditionState)); if (!node.EnabledState.Id.Value) { return(StatusCodes.BadConditionDisabled); } if (node.LockState.CurrentState.Id.Value == new NodeId(DsatsDemo.Objects.LockStateMachineType_Unlocked, NamespaceIndex)) { return(StatusCodes.BadConditionNotShelved); } // non-admins can only release their own locks. if (!CheckAdminAccess(context)) { if (!SessionHasLock(context, objectId)) { return(StatusCodes.BadUserAccessDenied); } } // revoke the lock. RevokeLockForSession(context, node.SessionId.Value, objectId); node.SessionId.Value = null; node.ClientUserId.Value = null; node.SubjectName.Value = null; node.Unlock(context); node.ReportEvent(context, node); node.ClearChangeMasks(context, true); return(ServiceResult.Good); }