-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOutlineManager.cs
293 lines (278 loc) · 12.1 KB
/
OutlineManager.cs
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
using System;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Collections.Generic;
using OutlineManager.Types;
using Newtonsoft.Json.Linq;
using System.Linq;
using Newtonsoft.Json;
using OutlineManagerExceptions;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace OutlineManager
{
public class Outline
{
public static string ApiUrl;
public static int KeysCount;
public static bool HasSsl;
/// <summary>
/// Welcome to OutlineAPI Manager!
/// </summary>
/// <param name="apiUrl">URL for access to Management API</param>
public Outline(string apiUrl)
{
ApiUrl = apiUrl;
KeysCount = GetKeys().Count;
}
/// <param name="apiUrl">URL for access to Management API</param>
/// <param name="hasSsl"><i>If your Outline Server hasn't <b>SSL connection</b> - set false</i></param>
public Outline(string apiUrl, bool hasSsl)
{
ApiUrl = apiUrl;
HasSsl = hasSsl;
KeysCount = GetKeys().Count();
}
private static bool CallRequest(string urlMethod, string method, out string data)
{
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(ApiUrl + "/" + urlMethod);
httpWebRequest.Method = method;
if (HasSsl == false)
httpWebRequest.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
using Stream stream = httpWebResponse.GetResponseStream();
using StreamReader streamReader = new StreamReader(stream);
data = streamReader.ReadToEnd();
}
return true;
}
catch (WebException exc)
{
data = null;
if (exc.Message == "The SSL connection could not be established, see inner exception.")
throw new OutlineAPIException("Your Outline Server hasn't SSL connection, please set hasSsl = false");
else if (exc.Message.Contains($"({ApiUrl}:443)"))
throw new OutlineManagerException("Server not found, please check API URL");
else if (exc.Message.Contains("(404) Not Found"))
throw new OutlineAPIException("Server returned 404: key not found");
else
throw new OutlineAPIException("Unknown Exception, please check API URL and see inner exception", exc);
}
}
private static bool CallRequest(string urlMethod, string method, JObject args, out string data)
{
try
{
WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
if (HasSsl == false)
ServicePointManager.ServerCertificateValidationCallback = (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true;
data = webClient.UploadString($"{ApiUrl}/{urlMethod}", method, args.ToString());
return true;
}
catch (WebException exc)
{
data = null;
if (exc.Message == "The SSL connection could not be established, see inner exception.")
throw new OutlineAPIException("Your Outline Server hasn't SSL connection, please set hasSsl = false");
else if (exc.Message.Contains($"({ApiUrl}:443)"))
throw new OutlineManagerException("Server not found, please check API URL");
else if (exc.Message.Contains("(404) Not Found"))
throw new OutlineAPIException("Server returned 404: key not found");
else
throw new OutlineAPIException("Unknown Exception, please check API URL and see inner exception", exc);
}
}
/// <summary>
/// Get Info about Outline Server
/// </summary>
/// <returns>Outline Server Info in <see cref="T:OutlineManager.Types.OutlineServer" /></returns>
/// <exception cref="OutlineManagerException"></exception>
public OutlineServer GetOutlineServer()
{
CallRequest("server", "GET", out var data);
return JsonConvert.DeserializeObject<OutlineServer>(data);
}
///<summary>
/// Changes the hostname for access keys.
/// Must be a valid hostname or IP address.
/// If it's a hostname, DNS must be set up independently of this API.
///</summary>
/// <returns><b>True</b>, if the hostname was changed succesfully</returns>
public bool ChangeHostname(string newHostname)
{
return CallRequest("server/hostname-for-access-keys", "PUT", new JObject { { "hostname", newHostname } }, out _);
}
///<summary>
/// Changes the default port for newly created access keys.
/// This can be a port already used for access keys.
///</summary>
/// <returns><b>True</b>, if the port was changed succesfully</returns>
public bool ChangePort(int newPort)
{
return CallRequest("server/port-for-new-access-keys", "PUT", new JObject { { "port", newPort } }, out _);
}
///<summary>
/// Rename the Outline Server
///</summary>
/// <returns><b>True</b>, if the server name was changed succesfully</returns>
public bool RenameServer(string newName)
{
return CallRequest("name", "PUT", new JObject { { "name", newName } }, out _);
}
///<summary>
/// Change Metrics Sharing
///</summary>
/// <returns><b>True</b>, if the metrics sharing was changed succesfully</returns>
public bool ChangeMetricsSharing(bool newParam)
{
return CallRequest("metrics/enabled", "PUT", new JObject { { "metricsEnabled", newParam } }, out _);
}
/// <summary>
/// Get Outline key in <see cref="T:OutlineManager.Types.OutlineKey" /> by ID
/// </summary>
/// <param name="id">ID of key</param>
/// <returns>Key in <see cref="T:OutlineManager.Types.OutlineKey" /></returns>
/// <exception cref="OutlineManagerException"></exception>
public OutlineKey GetKeyById(int id)
{
var list = GetKeys();
OutlineKey oKey = new OutlineKey() { Id = -1 };
foreach (var key in list)
if (key.Id == id)
oKey = key;
if (oKey.Id == -1)
throw new OutlineManagerException("Key not exist in your Outline Server");
else
return oKey;
}
/// <summary>
/// Get Outline key in <see cref="T:OutlineManager.Types.OutlineKey" /> by Name. <br></br><b>Avaiable methods:</b><br></br>- Equality by Name <br></br> - Equality by Name with Lower Case <br></br> - Starts with name with Lower Case
/// </summary>
/// <param name="name">Name of key</param>
/// <returns></returns>
/// <exception cref="OutlineManagerException"></exception>
public OutlineKey GetKeyByName(string name, SearchMethod searchMethod)
{
var list = GetKeys();
OutlineKey oKey = new OutlineKey() { Id = -1 };
foreach (var key in list)
switch (searchMethod)
{
case SearchMethod.StartsWith:
if (key.Name.StartsWith(name))
oKey = key;
break;
case SearchMethod.StartsWithToLower:
if (key.Name.ToLower().StartsWith(name.ToLower()))
oKey = key;
break;
case SearchMethod.Equality:
if (key.Name == name)
oKey = key;
break;
case SearchMethod.EqualityToLower:
if (key.Name.ToLower() == name.ToLower())
oKey = key;
break;
}
if (oKey.Id == -1)
throw new OutlineManagerException("Key not exist or not found by name in your Outline Server");
else
return oKey;
}
/// <summary>
/// Get Outline Keys from Outline Server
/// </summary>
/// <returns>List of <see cref="T:OutlineManager.Types.OutlineKey" /></returns>
public List<OutlineKey> GetKeys()
{
CallRequest("access-keys", "GET", out var data);
return (JObject.Parse(data)["accessKeys"] as JArray).ToObject<List<OutlineKey>>();
}
/// <summary>
/// Create Key in Outline Server
/// </summary>
/// <returns>Key information in <see cref="T:OutlineManager.Types.OutlineKey" /></returns>
public OutlineKey CreateKey()
{
CallRequest("access-keys", "POST", out var data);
return (JObject.Parse(data)).ToObject<OutlineKey>();
}
/// <summary>
/// Delete Key from Outline Server by ID
/// </summary>
/// <param name="id">ID of key</param>
/// <returns><see cref="true" />, if operation was successful</returns>
public bool DeleteKey(int id)
{
bool operation = CallRequest($"access-keys/{id}", "DELETE", out _);
return operation;
}
/// <summary>
/// Rename Key from Outline Server by ID
/// </summary>
/// <param name="id">ID of key</param>
/// <param name="name">Name of key</param>
/// <returns> <b><see cref="true" /></b>, if operation was successful</returns>
public bool RenameKey(int id, string name)
{
bool operation = CallRequest($"access-keys/{id}/name",
"PUT",
new JObject
{
{ "name", name }
}, out _);
return operation;
}
/// <summary>
/// Add Data Limit for Key from Outline Server by ID
/// </summary>
/// <param name="id">ID of key</param>
/// <param name="limitBytes">Limit for key in <b>bytes</b></param>
/// <returns> <b><see cref="true" /></b>, if operation was successful</returns>
public bool AddDataLimit(int id, long limitBytes)
{
bool operation = CallRequest($"access-keys/{id}/data-limit",
"PUT",
new JObject
{
{
"limit", new JObject
{
{"bytes", limitBytes}
}
}
},
out _);
return operation;
}
/// <summary>
/// Remove Data Limit for Key from Outline Server by ID
/// </summary>
/// <param name="id">ID of key</param>
/// <returns> <b><see cref="true" /></b>, if operation was successful</returns>
public bool DeleteDataLimit(int id)
{
bool operation = CallRequest($"access-keys/{id}/data-limit", "DELETE", out _);
return operation;
}
/// <summary>
/// Get Transferred Data from Outline Server
/// </summary>
/// <returns>List of keys in <see cref="T:OutlineManager.Types.TransferredData" /> with transferred data</returns>
public List<TransferredData> GetTransferredData()
{
bool operation = CallRequest("metrics/transfer", "GET", out var data);
var response = JObject.Parse(data)["bytesTransferredByUserId"] as JObject;
List<TransferredData> list = new List<TransferredData>();
foreach (var dat in response)
list.Add(new TransferredData() { KeyId = int.Parse(dat.Key), UsedBytes = (long)dat.Value });
return list;
}
}
}