-
Notifications
You must be signed in to change notification settings - Fork 18
/
method_node.go
160 lines (141 loc) · 4.48 KB
/
method_node.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright 2021 Converter Systems LLC. All rights reserved.
package server
import (
"context"
"sync"
"github.com/awcullen/opcua/ua"
)
// MethodNode is a Node class that describes the syntax of a object's Method.
type MethodNode struct {
sync.RWMutex
nodeID ua.NodeID
nodeClass ua.NodeClass
browseName ua.QualifiedName
displayName ua.LocalizedText
description ua.LocalizedText
rolePermissions []ua.RolePermissionType
accessRestrictions uint16
references []ua.Reference
executable bool
callMethodHandler func(context.Context, ua.CallMethodRequest) ua.CallMethodResult
}
var _ Node = (*MethodNode)(nil)
// NewMethodNode constructs a new MethodNode.
func NewMethodNode(nodeID ua.NodeID, browseName ua.QualifiedName, displayName ua.LocalizedText, description ua.LocalizedText, rolePermissions []ua.RolePermissionType, references []ua.Reference, executable bool) *MethodNode {
return &MethodNode{
nodeID: nodeID,
nodeClass: ua.NodeClassMethod,
browseName: browseName,
displayName: displayName,
description: description,
rolePermissions: rolePermissions,
accessRestrictions: 0,
references: references,
executable: executable,
}
}
// NodeID returns the NodeID attribute of this node.
func (n *MethodNode) NodeID() ua.NodeID {
return n.nodeID
}
// NodeClass returns the NodeClass attribute of this node.
func (n *MethodNode) NodeClass() ua.NodeClass {
return n.nodeClass
}
// BrowseName returns the BrowseName attribute of this node.
func (n *MethodNode) BrowseName() ua.QualifiedName {
return n.browseName
}
// DisplayName returns the DisplayName attribute of this node.
func (n *MethodNode) DisplayName() ua.LocalizedText {
return n.displayName
}
// Description returns the Description attribute of this node.
func (n *MethodNode) Description() ua.LocalizedText {
return n.description
}
// RolePermissions returns the RolePermissions attribute of this node.
func (n *MethodNode) RolePermissions() []ua.RolePermissionType {
return n.rolePermissions
}
// UserRolePermissions returns the RolePermissions attribute of this node for the current user.
func (n *MethodNode) UserRolePermissions(ctx context.Context) []ua.RolePermissionType {
filteredPermissions := []ua.RolePermissionType{}
session, ok := ctx.Value(SessionKey).(*Session)
if !ok {
return filteredPermissions
}
roles := session.UserRoles()
if len(roles) == 0 {
return filteredPermissions
}
rolePermissions := n.RolePermissions()
if rolePermissions == nil {
rolePermissions = session.Server().RolePermissions()
}
for _, rp := range rolePermissions {
for _, r := range roles {
if rp.RoleID == r {
filteredPermissions = append(filteredPermissions, rp)
}
}
}
return filteredPermissions
}
// References returns the References of this node.
func (n *MethodNode) References() []ua.Reference {
n.RLock()
res := n.references
n.RUnlock()
return res
}
// SetReferences sets the References of the Variable.
func (n *MethodNode) SetReferences(value []ua.Reference) {
n.Lock()
n.references = value
n.Unlock()
}
// Executable returns the Executable attribute of this node.
func (n *MethodNode) Executable() bool {
return n.executable
}
// UserExecutable returns the UserExecutable attribute of this node.
func (n *MethodNode) UserExecutable(ctx context.Context) bool {
if !n.executable {
return false
}
session, ok := ctx.Value(SessionKey).(*Session)
if !ok {
return false
}
roles := session.UserRoles()
rolePermissions := n.RolePermissions()
if rolePermissions == nil {
rolePermissions = session.Server().RolePermissions()
}
for _, role := range roles {
for _, rp := range rolePermissions {
if rp.RoleID == role && rp.Permissions&ua.PermissionTypeCall != 0 {
return true
}
}
}
return false
}
// SetCallMethodHandler sets the CallMethod of the Variable.
func (n *MethodNode) SetCallMethodHandler(value func(context.Context, ua.CallMethodRequest) ua.CallMethodResult) {
n.Lock()
n.callMethodHandler = value
n.Unlock()
}
// IsAttributeIDValid returns true if attributeId is supported for the node.
func (n *MethodNode) IsAttributeIDValid(attributeID uint32) bool {
switch attributeID {
case ua.AttributeIDNodeID, ua.AttributeIDNodeClass, ua.AttributeIDBrowseName,
ua.AttributeIDDisplayName, ua.AttributeIDDescription, ua.AttributeIDRolePermissions,
ua.AttributeIDUserRolePermissions, ua.AttributeIDExecutable, ua.AttributeIDUserExecutable:
return true
default:
return false
}
}