-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathLwm2mAccessControlObjectInstance.cs
More file actions
244 lines (218 loc) · 6.83 KB
/
Lwm2mAccessControlObjectInstance.cs
File metadata and controls
244 lines (218 loc) · 6.83 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using System;
using System.Threading.Tasks;
using Waher.Networking.CoAP;
using Waher.Persistence;
using Waher.Persistence.Attributes;
namespace Waher.Networking.LWM2M
{
/// <summary>
/// LWM2M Access Control object instance.
///
/// The Resource Instance ID MUST be the Short Server ID of a certain LwM2M Server for
/// which associated access rights are contained in the Resource Instance value.
///
/// The Resource Instance ID 0 is a specific ID, determining the ACL Instance which contains the
/// default access rights.
///
/// Each bit set in the Resource Instance value, grants an access right to the LwM2M Server to
/// the corresponding operation.
/// </summary>
public class Lwm2mAccessControlObjectInstance : Lwm2mObjectInstance, ICoapDeleteMethod
{
/// <summary>
/// The Object ID are applied for.
/// </summary>
private readonly Lwm2mResourceInteger aclObjectId;
/// <summary>
/// The Object Instance ID are applied for.
/// </summary>
private readonly Lwm2mResourceInteger aclObjectInstanceId;
/// <summary>
/// ACL privilges.
/// </summary>
private readonly Lwm2mResourceInteger aclPrivileges;
/// <summary>
/// Short Server ID of a certain LwM2M Server; only such an LwM2M Server can manage the
/// Resources of this Object Instance.
///
/// The specific value MAX_ID=65535 means this Access Control Object Instance is created
/// and modified during a Bootstrap phase only.
/// </summary>
private readonly Lwm2mResourceInteger accessControlOwner;
/// <summary>
/// LWM2M Access Control object instance.
/// </summary>
public Lwm2mAccessControlObjectInstance()
: this(0)
{
}
/// <summary>
/// LWM2M Access Control object instance.
/// </summary>
/// <param name="InstanceId">ID of object instance.</param>
public Lwm2mAccessControlObjectInstance(ushort InstanceId)
: base(2, InstanceId)
{
// E.1 LwM2M Object: LwM2M Security
// http://www.openmobilealliance.org/release/LightweightM2M/V1_0-20170208-A/OMA-TS-LightweightM2M-V1_0-20170208-A.pdf
this.aclObjectId = new Lwm2mResourceInteger("Object", 2, InstanceId, 0, false, false, null, false);
this.aclObjectInstanceId = new Lwm2mResourceInteger("Object Instance", 2, InstanceId, 1, false, false, null, false);
this.aclPrivileges = new Lwm2mResourceInteger("Privileges", 2, InstanceId, 2, true, false, null, false);
this.accessControlOwner = new Lwm2mResourceInteger("Owner", 2, InstanceId, 3, true, false, null, false);
}
/// <summary>
/// The Object ID are applied for.
/// </summary>
[DefaultValueNull]
public ushort? AclObjectId
{
get { return (ushort?)this.aclObjectId.IntegerValue; }
set { this.aclObjectId.IntegerValue = value; }
}
/// <summary>
/// The Object Instance ID are applied for.
/// </summary>
[DefaultValueNull]
public ushort? AclObjectInstanceId
{
get { return (ushort?)this.aclObjectInstanceId.IntegerValue; }
set { this.aclObjectInstanceId.IntegerValue = value; }
}
/// <summary>
/// Read, Observe, Discover, Write Attributes
/// </summary>
[DefaultValueNull]
public bool? CanRead
{
get { return this.GetPrivilege((byte)AclPrivilege.Read); }
set { this.SetPrivilege((byte)AclPrivilege.Read, value); }
}
/// <summary>
/// Write
/// </summary>
[DefaultValueNull]
public bool? CanWrite
{
get { return this.GetPrivilege((byte)AclPrivilege.Write); }
set { this.SetPrivilege((byte)AclPrivilege.Write, value); }
}
/// <summary>
/// Execute
/// </summary>
[DefaultValueNull]
public bool? CanExecute
{
get { return this.GetPrivilege((byte)AclPrivilege.Execute); }
set { this.SetPrivilege((byte)AclPrivilege.Execute, value); }
}
/// <summary>
/// Delete
/// </summary>
[DefaultValueNull]
public bool? CanDelete
{
get { return this.GetPrivilege((byte)AclPrivilege.Delete); }
set { this.SetPrivilege((byte)AclPrivilege.Delete, value); }
}
/// <summary>
/// Create
/// </summary>
[DefaultValueNull]
public bool? CanCreate
{
get { return this.GetPrivilege((byte)AclPrivilege.Create); }
set { this.SetPrivilege((byte)AclPrivilege.Create, value); }
}
/// <summary>
/// Short Server ID of a certain LwM2M Server; only such an LwM2M Server can manage the
/// Resources of this Object Instance.
///
/// The specific value MAX_ID=65535 means this Access Control Object Instance is created
/// and modified during a Bootstrap phase only.
/// </summary>
[DefaultValueNull]
public ushort? AccessControlOwner
{
get { return (ushort?)this.accessControlOwner.IntegerValue; }
set { this.accessControlOwner.IntegerValue = value; }
}
private bool? GetPrivilege(int Mask)
{
if (this.aclPrivileges.IntegerValue.HasValue)
return (this.aclPrivileges.IntegerValue.Value & Mask) != 0;
else
return null;
}
private void SetPrivilege(byte Mask, bool? Value)
{
byte b;
if (this.aclPrivileges.IntegerValue.HasValue)
b = (byte)this.aclPrivileges.IntegerValue.Value;
else
b = 0;
if (Value.HasValue && Value.Value)
b |= Mask;
else
b &= (byte)~Mask;
this.aclPrivileges.IntegerValue = b;
}
/// <summary>
/// If the DELETE method is allowed.
/// </summary>
public bool AllowsDELETE => true;
/// <summary>
/// Executes the DELETE method on the resource.
/// </summary>
/// <param name="Request">CoAP Request</param>
/// <param name="Response">CoAP Response</param>
/// <exception cref="CoapException">If an error occurred when processing the method.</exception>
public async Task DELETE(CoapMessage Request, CoapResponse Response)
{
if (this.Object.Client.State == Lwm2mState.Bootstrap &&
this.Object.Client.IsFromBootstrapServer(Request))
{
await this.DeleteBootstrapInfo();
await Response.ACK(CoapCode.Deleted);
}
else
await Response.RST(CoapCode.Unauthorized);
}
/// <summary>
/// Deletes any Bootstrap information.
/// </summary>
public override async Task DeleteBootstrapInfo()
{
if (!(this.ObjectId is null))
await Database.Delete(this);
}
/// <summary>
/// Applies any Bootstrap information.
/// </summary>
public override async Task ApplyBootstrapInfo()
{
if (this.ObjectId is null)
await Database.Insert(this);
else
await Database.Update(this);
}
/// <summary>
/// Executes the PUT method on the resource.
/// </summary>
/// <param name="Request">CoAP Request</param>
/// <param name="Response">CoAP Response</param>
/// <exception cref="CoapException">If an error occurred when processing the method.</exception>
public override Task PUT(CoapMessage Request, CoapResponse Response)
{
if (this.Object.Client.State == Lwm2mState.Bootstrap &&
this.Object.Client.IsFromBootstrapServer(Request))
{
return base.PUT(Request, Response);
}
else
{
Response.RST(CoapCode.Unauthorized);
return Task.CompletedTask;
}
}
}
}