|
1 | 1 | using Newtonsoft.Json; |
| 2 | +using Newtonsoft.Json.Linq; |
2 | 3 | using System; |
3 | 4 | using System.Linq; |
4 | 5 | using System.Net; |
@@ -55,10 +56,15 @@ public partial class WebUntisClient : IDisposable |
55 | 56 | private readonly HttpClient _client; |
56 | 57 |
|
57 | 58 | /// <summary> |
58 | | - /// Sesson id for requests |
| 59 | + /// Sesson id for json rpc requests |
59 | 60 | /// </summary> |
60 | 61 | private string _sessonId; |
61 | 62 |
|
| 63 | + /// <summary> |
| 64 | + /// Auth token for api requests |
| 65 | + /// </summary> |
| 66 | + private string _bearerToken; |
| 67 | + |
62 | 68 | /// <summary> |
63 | 69 | /// Initialize a new client |
64 | 70 | /// </summary> |
@@ -163,16 +169,37 @@ public async Task<bool> LoginAsync(string server, string loginName, string usern |
163 | 169 | throw responseModel.Error; |
164 | 170 | } |
165 | 171 |
|
166 | | - // Set data |
167 | 172 | _serverUrl = serverUrl; |
168 | 173 | _loginName = loginName; |
169 | 174 | _sessonId = responseModel.Result.SessionId; |
170 | 175 | _loggedIn = true; |
171 | 176 |
|
172 | | - // Get logged in user data |
| 177 | + // Get the api auth token and the logged in user |
| 178 | + Task<string> bearerTokenTask = GetBearerTokenAsync(ct); |
| 179 | + IUser[] users; |
| 180 | + if ((UserType)responseModel.Result.PersonType == Client.UserType.Student) // For student and teacher separate tasks |
| 181 | + { |
| 182 | + Task<Student[]> studentTask = GetStudentsAsync("getLoggedInStudent", ct); |
| 183 | + await Task.WhenAll(bearerTokenTask, studentTask); |
| 184 | + users = studentTask.Result; |
| 185 | + } |
| 186 | + else |
| 187 | + { |
| 188 | + Task<Teacher[]> teacherTask = GetTeachersAsync("getLoggedInTeacher", ct); |
| 189 | + await Task.WhenAll(bearerTokenTask, teacherTask); |
| 190 | + users = teacherTask.Result; |
| 191 | + } |
| 192 | + |
| 193 | + if (ct.IsCancellationRequested) // Check for cancellation |
| 194 | + { |
| 195 | + _ = LogoutAsync(); |
| 196 | + return false; |
| 197 | + } |
| 198 | + |
| 199 | + _bearerToken = bearerTokenTask.Result; |
| 200 | + |
173 | 201 | _userType = (UserType)responseModel.Result.PersonType; |
174 | | - IUser[] users = _userType == Client.UserType.Student ? (IUser[])await GetStudentsAsync(ct: ct) : await GetTeachersAsync(ct: ct); |
175 | | - _user = users.FirstOrDefault(u => u.Id == responseModel.Result.PersonId); |
| 202 | + _user = users.FirstOrDefault(user => user.Id == responseModel.Result.PersonId); |
176 | 203 |
|
177 | 204 | return true; |
178 | 205 | } |
@@ -211,6 +238,7 @@ public async Task LogoutAsync(string id = "Logout", CancellationToken ct = defau |
211 | 238 | _serverUrl = null; |
212 | 239 | _loginName = null; |
213 | 240 | _sessonId = null; |
| 241 | + _bearerToken = null; |
214 | 242 | _loggedIn = false; |
215 | 243 | } |
216 | 244 |
|
@@ -294,13 +322,45 @@ private async Task<TResult> MakeJSONRPCRequestAsync<TRequest, TResult>(string id |
294 | 322 | return responseModel.Result; |
295 | 323 | } |
296 | 324 |
|
| 325 | + /// <summary> |
| 326 | + /// Get the bearer auth token for the api authentication |
| 327 | + /// </summary> |
| 328 | + /// <param name="ct">Cancellation token</param> |
| 329 | + /// <returns>The bearer token</returns> |
| 330 | + /// <exception cref="HttpRequestException">Thrown when an error happend while the http request</exception> |
| 331 | + private async Task<string> GetBearerTokenAsync(CancellationToken ct) |
| 332 | + { |
| 333 | + HttpRequestMessage request = new HttpRequestMessage() |
| 334 | + { |
| 335 | + Method = HttpMethod.Get, |
| 336 | + RequestUri = new Uri(ServerUrl + "/WebUntis/api/token/new") |
| 337 | + }; |
| 338 | + SetRequestHeader(request.Headers); |
| 339 | + |
| 340 | + HttpResponseMessage response = await _client.SendAsync(request, ct); |
| 341 | + |
| 342 | + // Check cancellation token |
| 343 | + if (ct.IsCancellationRequested) |
| 344 | + return default; |
| 345 | + |
| 346 | + // Verify response |
| 347 | + if (response.StatusCode != HttpStatusCode.OK) |
| 348 | + throw new HttpRequestException($"There was an error while the http request (Code: {response.StatusCode})."); |
| 349 | + |
| 350 | + System.Diagnostics.Debug.WriteLine("Bearer"); |
| 351 | + return await response.Content.ReadAsStringAsync(); |
| 352 | + } |
| 353 | + |
297 | 354 | /// <summary> |
298 | 355 | /// Add the default headers to a WebUntis API request |
299 | 356 | /// </summary> |
300 | 357 | /// <param name="headers">The headers object to add</param> |
301 | | - private void SetRequestHeader(HttpHeaders headers) |
| 358 | + /// <param name="setBearer"><see langword="true"/> if the auth header should be set</param> |
| 359 | + private void SetRequestHeader(HttpHeaders headers, bool setBearer = false) |
302 | 360 | { |
303 | 361 | headers.Add("JSESSIONID", _sessonId); |
| 362 | + if (setBearer) |
| 363 | + (headers as HttpRequestHeaders).Authorization = new AuthenticationHeaderValue("Bearer", _bearerToken); |
304 | 364 | } |
305 | 365 |
|
306 | 366 | #region IDisposable |
|
0 commit comments