using System; using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEngine; namespace SUISS.Cloud { public class OAuthRequest : CustomYieldInstruction { private OAuthRequest(string endPoint, string username, string password, string scope) { if (this.IsLocked(endPoint)) { this._request = OAuthRequest._busy[endPoint]; } else { string value = "password"; WWWForm wwwform = new WWWForm(); wwwform.AddField("scope", scope); wwwform.AddField("grant_type", value); wwwform.AddField("password", password); wwwform.AddField("username", username); Dictionary headers = new Dictionary { { "Content-Type", "application/x-www-form-urlencoded" } }; this._request = new WWW(endPoint, wwwform.data, headers); OAuthRequest._busy[endPoint] = this._request; } } private OAuthRequest(string endPoint, string refreshToken, string scope) { if (this.IsLocked(endPoint)) { this._request = OAuthRequest._busy[endPoint]; } else { string value = "refresh_token"; WWWForm wwwform = new WWWForm(); wwwform.AddField("scope", scope); wwwform.AddField("grant_type", value); wwwform.AddField("refresh_token", refreshToken); Dictionary headers = new Dictionary { { "Content-Type", "application/x-www-form-urlencoded" } }; this._request = new WWW(endPoint, wwwform.data, headers); OAuthRequest._busy[endPoint] = this._request; } } public static OAuthRequest LoginPassword(string endPoint, string username, string password, string scope) { return new OAuthRequest(endPoint, username, password, scope); } public static OAuthRequest LoginRefreshToken(string endPoint, string refreshToken, string scope) { return new OAuthRequest(endPoint, refreshToken, scope); } public bool IsDone { get { this.ProcessResults(); return this._resultsProcessed; } } public OAuthRequest.OAuthResponse Result { get { this.ProcessResults(); return this._result; } } public ApiError Error { get { this.ProcessResults(); return this._error; } } public int HttpStatus { get { if (this._request.isDone) { if (this._request.responseHeaders.ContainsKey("STATUS")) { Match match = Regex.Match(this._request.responseHeaders["STATUS"], "HTTP\\/\\d.\\d\\s(\\d{1,3})"); if (match.Success) { return int.Parse(match.Groups[1].Value); } } return 0; } return -1; } } public override bool keepWaiting { get { return !this._request.isDone; } } private bool IsLocked(string endPoint) { return OAuthRequest._busy.ContainsKey(endPoint) && !OAuthRequest._busy[endPoint].isDone; } private void ProcessResults() { if (this._request.isDone && !this._resultsProcessed) { int httpStatus = this.HttpStatus; if (httpStatus <= 0) { this._error = new ApiError { Status = 0, Error = (this._request.error ?? "unknown error"), ErrorCode = 0, ServerError = false, NoInternet = true }; } else if (200 <= httpStatus && httpStatus < 300 && !string.IsNullOrEmpty(this._request.text)) { bool flag = false; object json = Json.Decode(this._request.text, ref flag); if (!flag) { this._error = new ApiError { Status = 0, Error = "server returned invalid json", ErrorCode = 0, ServerError = true, NoInternet = false }; } else if (this.GetJsonString(json, "token_type", string.Empty) == "bearer") { string jsonString = this.GetJsonString(json, "access_token", string.Empty); string jsonString2 = this.GetJsonString(json, "refresh_token", string.Empty); string jsonString3 = this.GetJsonString(json, "scope", string.Empty); DateTime expires = DateTime.UtcNow.AddSeconds((double)this.GetJsonInt(json, "expires_in", 0)); this._result = new OAuthRequest.OAuthResponse { AccessToken = new AccessToken(jsonString, jsonString3, expires), RefreshToken = jsonString2, Scope = jsonString3 }; } else { this._error = new ApiError { Status = httpStatus, Error = "server returned unknown token type.", ErrorCode = 0, ServerError = true, NoInternet = false }; } } else { bool flag2 = false; object obj = Json.Decode(this._request.text, ref flag2); if (flag2) { Dictionary dictionary = obj as Dictionary; if (dictionary != null && dictionary.ContainsKey("code") && dictionary.ContainsKey("message") && dictionary.ContainsKey("error")) { this._error = new ApiError { Status = this.GetJsonInt(obj, "code", 0), Error = this.GetJsonString(obj, "message", string.Empty), ErrorCode = this.GetJsonInt(obj, "error", 0), ServerError = false, NoInternet = false }; } else { flag2 = false; } } if (!flag2) { this._error = new ApiError { Status = httpStatus, Error = (string.IsNullOrEmpty(this._request.text) ? "server returned nothing" : this._request.text), ErrorCode = 0, ServerError = true, NoInternet = false }; } } this._resultsProcessed = true; } } private string GetJsonString(object json, string key, string defaultValue) { if (json is Dictionary) { Dictionary dictionary = (Dictionary)json; if (dictionary.ContainsKey(key) && dictionary[key] is string) { return (string)dictionary[key]; } } return defaultValue; } private int GetJsonInt(object json, string key, int defaultValue) { if (json is Dictionary) { Dictionary dictionary = (Dictionary)json; if (dictionary.ContainsKey(key) && dictionary[key] is double) { return (int)((double)dictionary[key]); } } return defaultValue; } private static Dictionary _busy = new Dictionary(); private WWW _request; private ApiError _error; private OAuthRequest.OAuthResponse _result; private bool _resultsProcessed; public class OAuthResponse { public AccessToken AccessToken { get; set; } public string RefreshToken { get; set; } public string Scope { get; set; } } } }