2022-06-23 22:50:05 -05:00
|
|
|
using Meziantou.Framework.Win32;
|
2023-05-04 00:18:30 -05:00
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
2022-06-23 22:50:05 -05:00
|
|
|
using System.Reflection;
|
2023-05-04 00:18:30 -05:00
|
|
|
using System.Threading.Tasks;
|
2022-06-23 22:50:05 -05:00
|
|
|
|
|
|
|
|
namespace Microsoft.Zune.Service
|
|
|
|
|
{
|
|
|
|
|
internal static partial class Escargot
|
|
|
|
|
{
|
2023-04-28 19:06:40 -05:00
|
|
|
const string ESCARGOT_NOTRST_URL = "http://login.zunes.me/NotRST.srf";
|
2022-06-23 22:50:05 -05:00
|
|
|
const string HEADER_X_USER = "X-User";
|
|
|
|
|
const string HEADER_X_PASS = "X-Password";
|
|
|
|
|
const string HEADER_X_TOKEN = "X-Token";
|
|
|
|
|
|
2023-05-04 00:18:30 -05:00
|
|
|
internal static readonly HttpClient _client = new();
|
2022-06-23 22:50:05 -05:00
|
|
|
private static string _token;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the username of the currently authenticated user.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static string Username { get; private set; }
|
|
|
|
|
|
|
|
|
|
public static bool HasToken => _token != null;
|
|
|
|
|
|
|
|
|
|
public static void CacheToken()
|
|
|
|
|
{
|
|
|
|
|
if (_token == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Ensure that alternative Zune launchers can only access
|
|
|
|
|
// credentials given explicitly to them by the user.
|
|
|
|
|
string appName = Assembly.GetEntryAssembly().FullName;
|
|
|
|
|
|
|
|
|
|
CredentialManager.DeleteCredential(appName);
|
|
|
|
|
CredentialManager.WriteCredential(appName, Username, _token, CredentialPersistence.LocalMachine);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool ReadCachedToken()
|
|
|
|
|
{
|
|
|
|
|
string appName = Assembly.GetEntryAssembly().FullName;
|
|
|
|
|
|
|
|
|
|
var cred = CredentialManager.ReadCredential(appName);
|
|
|
|
|
if (cred == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Username = cred.UserName;
|
|
|
|
|
_token = cred.Password;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void ClearToken()
|
|
|
|
|
{
|
|
|
|
|
_token = null;
|
|
|
|
|
Username = null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-04 00:18:30 -05:00
|
|
|
public static bool TrySignIn(string username, string password)
|
|
|
|
|
{
|
|
|
|
|
HttpRequestMessage request = new(HttpMethod.Post, ESCARGOT_NOTRST_URL);
|
|
|
|
|
request.Headers.TryAddWithoutValidation(HEADER_X_USER, username);
|
|
|
|
|
request.Headers.TryAddWithoutValidation(HEADER_X_PASS, password);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var response =
|
|
|
|
|
#if NET5_0_OR_GREATER
|
|
|
|
|
_client.Send(request);
|
|
|
|
|
#else
|
|
|
|
|
Task.Run(() => _client.SendAsync(request)).Result;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
|
|
|
|
|
|
string token = response.Headers.GetValues(HEADER_X_TOKEN).FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
return TrySetCredentials(token, username);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void AuthenticateRequest(HttpRequestMessage request)
|
|
|
|
|
{
|
|
|
|
|
request.Headers.Authorization = new("Bearer", _token);
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-23 22:50:05 -05:00
|
|
|
private static bool TrySetCredentials(string token, string username)
|
|
|
|
|
{
|
|
|
|
|
if (token == null)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Username = username;
|
|
|
|
|
_token = token;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|