1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.Net;
|
---|
4 | using JetBrains.Annotations;
|
---|
5 | using Utf8Json;
|
---|
6 | using Webserver.Permissions;
|
---|
7 |
|
---|
8 | namespace Webserver.WebAPI.APIs.Permissions {
|
---|
9 | [UsedImplicitly]
|
---|
10 | public class WebModules : AbsRestApi {
|
---|
11 | private const string propertyModule = "module";
|
---|
12 | private const string propertyPermissionLevelGlobal = "permissionLevelGlobal";
|
---|
13 | private const string propertyPermissionLevelPerMethod = "permissionLevelPerMethod";
|
---|
14 | private const string propertyIsDefault = "isDefault";
|
---|
15 |
|
---|
16 |
|
---|
17 | private static readonly byte[] jsonKeyModule = JsonWriter.GetEncodedPropertyNameWithBeginObject (propertyModule);
|
---|
18 | private static readonly byte[] jsonKeyPermissionLevelGlobal = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator (propertyPermissionLevelGlobal);
|
---|
19 | private static readonly byte[] jsonKeyPermissionLevelPerMethod = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator (propertyPermissionLevelPerMethod);
|
---|
20 | private static readonly byte[] jsonKeyIsDefault = JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator (propertyIsDefault);
|
---|
21 |
|
---|
22 | private static readonly byte[][] jsonMethodNameKeys;
|
---|
23 |
|
---|
24 | static WebModules () {
|
---|
25 | jsonMethodNameKeys = new byte[(int)ERequestMethod.Count][];
|
---|
26 | for (int i = 0; i < jsonMethodNameKeys.Length; i++) {
|
---|
27 | ERequestMethod method = (ERequestMethod)i;
|
---|
28 | jsonMethodNameKeys [i] = JsonWriter.GetEncodedPropertyName (method.ToStringCached ());
|
---|
29 | }
|
---|
30 | }
|
---|
31 |
|
---|
32 | private static AdminWebModules ModulesInstance => AdminWebModules.Instance;
|
---|
33 |
|
---|
34 | protected override void HandleRestGet (RequestContext _context) {
|
---|
35 | string id = _context.RequestPath;
|
---|
36 |
|
---|
37 | PrepareEnvelopedResult (out JsonWriter writer);
|
---|
38 |
|
---|
39 | if (string.IsNullOrEmpty (id)) {
|
---|
40 |
|
---|
41 | writer.WriteBeginArray ();
|
---|
42 |
|
---|
43 | bool first = true;
|
---|
44 | foreach (AdminWebModules.WebModule module in ModulesInstance.GetModules ()) {
|
---|
45 | if (!first) {
|
---|
46 | writer.WriteValueSeparator ();
|
---|
47 | }
|
---|
48 |
|
---|
49 | first = false;
|
---|
50 |
|
---|
51 | writeModuleJson (ref writer, module);
|
---|
52 | }
|
---|
53 |
|
---|
54 | writer.WriteEndArray ();
|
---|
55 |
|
---|
56 | SendEnvelopedResult (_context, ref writer);
|
---|
57 | return;
|
---|
58 | }
|
---|
59 |
|
---|
60 | writer.WriteRaw (WebUtils.JsonEmptyData);
|
---|
61 | SendEnvelopedResult (_context, ref writer, HttpStatusCode.BadRequest);
|
---|
62 | }
|
---|
63 |
|
---|
64 | private void writeModuleJson (ref JsonWriter _writer, AdminWebModules.WebModule _module) {
|
---|
65 | _writer.WriteRaw (jsonKeyModule);
|
---|
66 | _writer.WriteString (_module.Name);
|
---|
67 | _writer.WriteRaw (jsonKeyPermissionLevelGlobal);
|
---|
68 | _writer.WriteInt32 (_module.LevelGlobal);
|
---|
69 | _writer.WriteRaw (jsonKeyPermissionLevelPerMethod);
|
---|
70 |
|
---|
71 | _writer.WriteBeginObject ();
|
---|
72 |
|
---|
73 | if (_module.LevelPerMethod != null) {
|
---|
74 | bool first = true;
|
---|
75 | for (int iMethod = 0; iMethod < _module.LevelPerMethod.Length; iMethod++) {
|
---|
76 | int methodLevel = _module.LevelPerMethod [iMethod];
|
---|
77 |
|
---|
78 | if (methodLevel == AdminWebModules.MethodLevelNotSupported) {
|
---|
79 | continue;
|
---|
80 | }
|
---|
81 |
|
---|
82 | if (!first) {
|
---|
83 | _writer.WriteValueSeparator ();
|
---|
84 | }
|
---|
85 |
|
---|
86 | first = false;
|
---|
87 |
|
---|
88 | _writer.WriteRaw (jsonMethodNameKeys [iMethod]);
|
---|
89 | if (methodLevel == AdminWebModules.MethodLevelInheritGlobal) {
|
---|
90 | _writer.WriteString (AdminWebModules.MethodLevelInheritKeyword);
|
---|
91 | } else {
|
---|
92 | _writer.WriteInt32 (methodLevel);
|
---|
93 | }
|
---|
94 | }
|
---|
95 | }
|
---|
96 |
|
---|
97 | _writer.WriteEndObject ();
|
---|
98 |
|
---|
99 | _writer.WriteRaw (jsonKeyIsDefault);
|
---|
100 | _writer.WriteBoolean (_module.IsDefault);
|
---|
101 |
|
---|
102 | _writer.WriteEndObject ();
|
---|
103 | }
|
---|
104 |
|
---|
105 | protected override void HandleRestPost (RequestContext _context, IDictionary<string, object> _jsonInput, byte[] _jsonInputData) {
|
---|
106 | string id = _context.RequestPath;
|
---|
107 |
|
---|
108 | if (string.IsNullOrEmpty (id)) {
|
---|
109 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.NO_MODULE);
|
---|
110 | return;
|
---|
111 | }
|
---|
112 |
|
---|
113 | if (!AdminWebModules.Instance.IsKnownModule (id)) {
|
---|
114 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_MODULE);
|
---|
115 | return;
|
---|
116 | }
|
---|
117 |
|
---|
118 | AdminWebModules.WebModule module = AdminWebModules.Instance.GetModule (id);
|
---|
119 |
|
---|
120 | if (_jsonInput.ContainsKey (propertyPermissionLevelGlobal)) {
|
---|
121 | if (!JsonCommons.TryGetJsonField (_jsonInput, propertyPermissionLevelGlobal, out int permissionLevelGlobal)) {
|
---|
122 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_PERMISSION_LEVEL_GLOBAL);
|
---|
123 | return;
|
---|
124 | }
|
---|
125 |
|
---|
126 | module = module.SetLevelGlobal (permissionLevelGlobal);
|
---|
127 | }
|
---|
128 |
|
---|
129 | if (_jsonInput.TryGetValue (propertyPermissionLevelPerMethod, out object perLevelField)) {
|
---|
130 | if (perLevelField is not IDictionary<string, object> perLevelObj) {
|
---|
131 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_PERMISSION_LEVEL_PER_METHOD_PROPERTY);
|
---|
132 | return;
|
---|
133 | }
|
---|
134 |
|
---|
135 | foreach ((string property, object valueObj) in perLevelObj) {
|
---|
136 | if (!EnumUtils.TryParse (property, out ERequestMethod method, true)) {
|
---|
137 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_METHOD_NAME);
|
---|
138 | return;
|
---|
139 | }
|
---|
140 |
|
---|
141 | if (module.LevelPerMethod == null || module.LevelPerMethod [(int)method] == AdminWebModules.MethodLevelNotSupported) {
|
---|
142 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.UNSUPPORTED_METHOD);
|
---|
143 | return;
|
---|
144 | }
|
---|
145 |
|
---|
146 | int permissionLevel;
|
---|
147 |
|
---|
148 | if (valueObj is string valueString) {
|
---|
149 | if (!valueString.EqualsCaseInsensitive (AdminWebModules.MethodLevelInheritKeyword)) {
|
---|
150 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_PERMISSION_STRING);
|
---|
151 | return;
|
---|
152 | }
|
---|
153 |
|
---|
154 | permissionLevel = AdminWebModules.MethodLevelInheritGlobal;
|
---|
155 | } else if (valueObj is double valueDbl) {
|
---|
156 | try {
|
---|
157 | permissionLevel = (int)valueDbl;
|
---|
158 | } catch (Exception) {
|
---|
159 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_PERMISSION_VALUE);
|
---|
160 | return;
|
---|
161 | }
|
---|
162 | } else {
|
---|
163 | SendEmptyResponse (_context, HttpStatusCode.BadRequest, _jsonInputData, EApiErrorCode.INVALID_PERMISSION_VALUE_TYPE);
|
---|
164 | return;
|
---|
165 | }
|
---|
166 |
|
---|
167 | module = module.SetLevelForMethod (method, permissionLevel);
|
---|
168 | }
|
---|
169 | }
|
---|
170 |
|
---|
171 | ModulesInstance.AddModule (module);
|
---|
172 |
|
---|
173 | SendEmptyResponse (_context, HttpStatusCode.Created);
|
---|
174 | }
|
---|
175 |
|
---|
176 | protected override void HandleRestDelete (RequestContext _context) {
|
---|
177 | string id = _context.RequestPath;
|
---|
178 |
|
---|
179 | bool removed = ModulesInstance.RemoveModule (id);
|
---|
180 |
|
---|
181 | SendEmptyResponse (_context, removed ? HttpStatusCode.NoContent : HttpStatusCode.NotFound);
|
---|
182 | }
|
---|
183 |
|
---|
184 | protected override bool AllowPostWithId => true;
|
---|
185 |
|
---|
186 | public override int[] DefaultMethodPermissionLevels () => new[] {
|
---|
187 | AdminWebModules.MethodLevelNotSupported,
|
---|
188 | AdminWebModules.MethodLevelInheritGlobal,
|
---|
189 | AdminWebModules.MethodLevelInheritGlobal,
|
---|
190 | AdminWebModules.MethodLevelNotSupported,
|
---|
191 | AdminWebModules.MethodLevelInheritGlobal
|
---|
192 | };
|
---|
193 | }
|
---|
194 | }
|
---|