protected async Task <XdtsTokenResponse> FetchXdtsToken(string aadToken, string scid, IEnumerable <string> sandboxes)
        {
            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, this.AuthContext.XtdsEndpoint);

                    var requestContent = JsonConvert.SerializeObject(new XdtsTokenRequest(scid, sandboxes));
                    requestMsg.Content = new StringContent(requestContent);

                    // Add the aadToken header without validation as the framework
                    // does not like the values returned for aadTokens for MSA accounts.
                    requestMsg.Headers.TryAddWithoutValidation("Authorization", aadToken);

                    return(requestMsg);
                })).Response;
                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch xdts Token succeeded.");

                var token = await response.Content.DeserializeJsonAsync <XdtsTokenResponse>();

                string key = XdtsTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, scid, sandboxes);
                this.ETokenCache.Value.UpdateToken(key, token);

                return(token);
            }
        }
        /// <summary>
        /// Downloads a savedgame from Connected Storage.
        /// </summary>
        /// <param name="xuid">The xuid of the user</param>
        /// <param name="serviceConfigurationId">The service configuration ID (SCID) of the title</param>
        /// <param name="sandbox">The target sandbox id for title storage</param>
        /// <param name="pathAndFileName">Blob path and file name on XboxLive service.</param>
        /// <returns>The byte array contains downloaded blob data</returns>
        public static async Task <SavedGameV2Response> DownloadSavedGameAsync(ulong xuid, Guid serviceConfigurationId, string sandbox, string pathAndFileName)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, new Uri(baseUri, $"/connectedstorage/users/xuid({xuid})/scids/{serviceConfigurationId}/savedgames/{pathAndFileName}"));
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                })).Response;
                response.EnsureSuccessStatusCode();

                Log.WriteLog($"DownloadSavedGameAsync for xuid: {xuid}, scid: {serviceConfigurationId}, sandbox: {sandbox}");

                JsonSerializer jsonSerializer = JsonSerializer.CreateDefault();
                using (StreamReader streamReader = new StreamReader(await response.Content.ReadAsStreamAsync()))
                {
                    using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        return(jsonSerializer.Deserialize <SavedGameV2Response>(jsonTextReader));
                    }
                }
            }
        }
        /// <summary>
        /// Downloads atom from Connected Storage.
        /// </summary>
        /// <param name="xuid">The xuid of the user</param>
        /// <param name="serviceConfigurationId">The service configuration ID (SCID) of the title</param>
        /// <param name="sandbox">The target sandbox id for title storage</param>
        /// <param name="pathAndFileName">Blob path and file name to store on XboxLive service.(example: "foo\bar\blob.txt")</param>
        /// <returns>The byte array contains downloaded blob data</returns>
        public static async Task <byte[]> DownloadAtomAsync(ulong xuid, Guid serviceConfigurationId, string sandbox, string pathAndFileName)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, new Uri(baseUri, $"/connectedstorage/users/xuid({xuid})/scids/{serviceConfigurationId}/{pathAndFileName},binary"));
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");
                    requestMsg.Headers.AcceptEncoding.Add(StringWithQualityHeaderValue.Parse("gzip"));

                    return(requestMsg);
                })).Response;
                response.EnsureSuccessStatusCode();

                Log.WriteLog($"DownloadAtomAsync for xuid: {xuid}, scid: {serviceConfigurationId}, sandbox: {sandbox}");

                // if the response came gzip encoded, we need to decompress it
                if (response.Content.Headers.ContentEncoding.FirstOrDefault() == "gzip")
                {
                    using (GZipStream gzipStream = new GZipStream(await response.Content.ReadAsStreamAsync(), CompressionMode.Decompress))
                    {
                        using (var memoryStream = new MemoryStream())
                        {
                            await gzipStream.CopyToAsync(memoryStream);

                            return(memoryStream.ToArray());
                        }
                    }
                }
                else
                {
                    return(await response.Content.ReadAsByteArrayAsync());
                }
            }
        }
        private static async Task <UserResetJob> SubmitJobAsync(string sandbox, string scid, string xuid)
        {
            var job = new UserResetJob {
                Sandbox = sandbox, Scid = scid
            };

            using (var submitRequest = new XboxLiveHttpRequest(true, scid, sandbox))
            {
                var response = await submitRequest.SendAsync(() =>
                {
                    var requestMsg     = new HttpRequestMessage(HttpMethod.Post, new Uri(baseUri, "submitJob"));
                    var requestContent = JsonConvert.SerializeObject(new JobSubmitReqeust(scid, xuid));
                    requestMsg.Content = new StringContent(requestContent);
                    requestMsg.Headers.Add("x-xbl-contract-version", "100");

                    return(requestMsg);
                });

                response.Response.EnsureSuccessStatusCode();

                // remove "" if found one.
                string responseContent = await response.Response.Content.ReadAsStringAsync();

                job.JobId         = responseContent.Trim(new char[] { '\\', '\"' });
                job.CorrelationId = response.CorrelationId;

                Log.WriteLog($"Submitting delete job for scid:{scid}, user:{xuid}, sandbox:{sandbox} succeeded. Jobid: {job.JobId}");
            }

            return(job);
        }
Exemple #5
0
        /// <summary>
        /// Deletes a blob from title storage.
        /// </summary>
        /// <param name="serviceConfigurationId">The service configuration ID (SCID) of the title</param>
        /// <param name="sandbox">The target sandbox id for title storage</param>
        /// <param name="pathAndFileName">Blob path and file name to store on XboxLive service.(example: "foo\bar\blob.txt")</param>
        /// <param name="blobType">Title storage blob type</param>
        public static async Task DeleteGlobalStorageBlobAsync(string serviceConfigurationId, string sandbox, string pathAndFileName, TitleStorageBlobType blobType)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                var response = await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Delete, new Uri(baseUri, $"/global/scids/{serviceConfigurationId}/data/{pathAndFileName},{blobType.ToString().ToLower()}"));
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                });

                Log.WriteLog($"DeleteGlobalStorageBlobAsync for scid: {serviceConfigurationId}, sandbox: {sandbox}");
            }
        }
Exemple #6
0
        /// <summary>
        /// Downloads blob data from title storage.
        /// </summary>
        /// <param name="serviceConfigurationId">The service configuration ID (SCID) of the title</param>
        /// <param name="sandbox">The target sandbox id for title storage</param>
        /// <param name="pathAndFileName">Blob path and file name to store on XboxLive service.(example: "foo\bar\blob.txt")</param>
        /// <param name="blobType">Title storage blob type</param>
        /// <returns>The byte array contains downloaded blob data</returns>
        public static async Task <byte[]> DownloadGlobalStorageBlobAsync(string serviceConfigurationId, string sandbox, string pathAndFileName, TitleStorageBlobType blobType)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, new Uri(baseUri, $"/global/scids/{serviceConfigurationId}/data/{pathAndFileName},{blobType.ToString().ToLower()}"));
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                })).Response;
                response.EnsureSuccessStatusCode();

                Log.WriteLog($"DownloadGlobalStorageBlobAsync for scid: {serviceConfigurationId}, sandbox: {sandbox}");

                return(await response.Content.ReadAsByteArrayAsync());
            }
        }
        internal static async Task <ListTitleDataResponse> ListSavedGamesAsync(ulong xuid, string serviceConfigurationId, string sandbox, string path, uint maxItems,
                                                                               uint skipItems, string continuationToken)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                var uriBuilder = new UriBuilder(baseUri)
                {
                    Path = $"/connectedstorage/users/xuid({xuid})/scids/{serviceConfigurationId}/{path}"
                };

                AppendPagingInfo(ref uriBuilder, maxItems, skipItems, continuationToken);

                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, uriBuilder.Uri);
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                })).Response;

                // Return empty list on 404
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    return(new ListTitleDataResponse());
                }

                response.EnsureSuccessStatusCode();

                Log.WriteLog($"ListSavedGamesAsync for xuid: {xuid}, scid: {serviceConfigurationId}, sandbox: {sandbox}");

                JsonSerializer jsonSerializer = JsonSerializer.CreateDefault();
                using (StreamReader streamReader = new StreamReader(await response.Content.ReadAsStreamAsync()))
                {
                    using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
                    {
                        return(jsonSerializer.Deserialize <ListTitleDataResponse>(jsonTextReader));
                    }
                }
            }
        }
        private static async Task <JobStatusResponse> CheckJobStatus(UserResetJob userResetJob)
        {
            using (var submitRequest = new XboxLiveHttpRequest(true, userResetJob.Scid, userResetJob.Sandbox))
            {
                XboxLiveHttpResponse xblResponse = await submitRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, new Uri(baseUri, "jobs/" + userResetJob.JobId));
                    if (!string.IsNullOrEmpty(userResetJob.CorrelationId))
                    {
                        requestMsg.Headers.Add("X-XblCorrelationId", userResetJob.CorrelationId);
                    }
                    requestMsg.Headers.Add("x-xbl-contract-version", "100");

                    return(requestMsg);
                });

                // There is a chance if polling too early for job status, it will return 400.
                // We threat it as job queue and wait for next poll.
                if (xblResponse.Response.StatusCode == System.Net.HttpStatusCode.BadRequest)
                {
                    return(new JobStatusResponse
                    {
                        Status = "Queued",
                        JobId = userResetJob.JobId
                    });
                }

                // Throw HttpRequestExcetpion for other HTTP status code
                xblResponse.Response.EnsureSuccessStatusCode();

                string responseConent = await xblResponse.Response.Content.ReadAsStringAsync();

                var jobstatus = JsonConvert.DeserializeObject <JobStatusResponse>(responseConent);

                Log.WriteLog($"Checking {userResetJob.JobId} job stauts: {jobstatus.Status}");

                return(jobstatus);
            }
        }
Exemple #9
0
        /// <summary>
        /// Get title global storage quota information.
        /// </summary>
        /// <param name="serviceConfigurationId">The service configuration ID (SCID) of the title</param>
        /// <param name="sandbox">The target sandbox id for title storage</param>
        /// <returns>GlobalStorageQuotaInfo object contains quota info</returns>
        public static async Task <GlobalStorageQuotaInfo> GetGlobalStorageQuotaAsync(string serviceConfigurationId, string sandbox)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, new Uri(baseUri, "/global/scids/" + serviceConfigurationId));
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                })).Response;
                response.EnsureSuccessStatusCode();

                string content = await response.Content.ReadAsStringAsync();

                JObject storageQuota        = JObject.Parse(content);
                GlobalStorageQuotaInfo info = storageQuota["quotaInfo"].ToObject <GlobalStorageQuotaInfo>();

                Log.WriteLog($"GetGlobalStorageQuotaAsync for scid: {serviceConfigurationId}, sandbox: {sandbox}");

                return(info);
            }
        }
Exemple #10
0
        internal static async Task <TitleStorageBlobMetadataResult> GetGlobalStorageBlobMetaDataAsync(string serviceConfigurationId, string sandbox, string path, uint maxItems,
                                                                                                      uint skipItems, string continuationToken)
        {
            using (var request = new XboxLiveHttpRequest(true, serviceConfigurationId, sandbox))
            {
                var uriBuilder = new UriBuilder(baseUri)
                {
                    Path = $"/global/scids/{serviceConfigurationId}/data/{path}"
                };

                AppendPagingInfo(ref uriBuilder, maxItems, skipItems, continuationToken);

                HttpResponseMessage response = (await request.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Get, uriBuilder.Uri);
                    requestMsg.Headers.Add("x-xbl-contract-version", "1");

                    return(requestMsg);
                })).Response;

                // Return empty list on 404
                if (response.StatusCode == HttpStatusCode.NotFound)
                {
                    return(new TitleStorageBlobMetadataResult());
                }

                response.EnsureSuccessStatusCode();

                Log.WriteLog($"GetGlobalStorageBlobMetaDataAsync for scid: {serviceConfigurationId}, sandbox: {sandbox}");

                string stringContent = await response.Content.ReadAsStringAsync();

                JObject storageMetadata = JObject.Parse(stringContent);
                var     result          = new TitleStorageBlobMetadataResult
                {
                    TotalItems             = storageMetadata["pagingInfo"]["totalItems"].Value <uint>(),
                    ContinuationToken      = storageMetadata["pagingInfo"]["continuationToken"].Value <string>(),
                    ServiceConfigurationId = serviceConfigurationId,
                    Sandbox = sandbox,
                    Path    = path
                };

                var array         = (JArray)storageMetadata["blobs"];
                var metadataArray = array.Select((o) =>
                {
                    string fileName          = o["fileName"].Value <string>();
                    ulong size               = o["size"].Value <ulong>();
                    var filePathAndTypeArray = fileName.Split(',');
                    if (filePathAndTypeArray.Length != 2)
                    {
                        throw new FormatException("Invalid file name format in TitleStorageBlobMetadata response");
                    }
                    if (!Enum.TryParse(filePathAndTypeArray[1], true, out TitleStorageBlobType type))
                    {
                        throw new FormatException("Invalid file type in TitleStorageBlobMetadata response");
                    }

                    return(new TitleStorageBlobMetadata
                    {
                        Path = filePathAndTypeArray[0],
                        Size = size,
                        Type = type
                    });
                }).ToArray();

                result.Items = metadataArray;

                return(result);
            }
        }
        protected async Task <XasTokenResponse> FetchXstsToken(string msaToken, string sandbox)
        {
            // Get XASU token
            XasTokenResponse token = null;

            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, ClientSettings.Singleton.XASUEndpoint);

                    XasuTokenRequest xasuTokenRequest = new XasuTokenRequest();
                    xasuTokenRequest.Properties["SiteName"] = "user.auth.xboxlive.com";
                    xasuTokenRequest.Properties["RpsTicket"] = $"d={msaToken}";

                    var requestContent = JsonConvert.SerializeObject(xasuTokenRequest);
                    requestMsg.Content = new StringContent(requestContent);
                    requestMsg.Content.Headers.ContentType.MediaType = "application/json";

                    return(requestMsg);
                })).Response;

                // Get XASU token with MSA token
                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch XASU token succeeded.");

                token = await response.Content.DeserializeJsonAsync <XasTokenResponse>();
            }

            // Get XSTS token
            using (var tokenRequest = new XboxLiveHttpRequest())
            {
                HttpResponseMessage response = (await tokenRequest.SendAsync(() =>
                {
                    var requestMsg = new HttpRequestMessage(HttpMethod.Post, ClientSettings.Singleton.XSTSEndpoint);

                    XstsTokenRequest xstsTokenRequest = new XstsTokenRequest(sandbox)
                    {
                        RelyingParty = "http://xboxlive.com"
                    };
                    xstsTokenRequest.Properties["UserTokens"] = new[] { token.Token };

                    var requestContent = JsonConvert.SerializeObject(xstsTokenRequest);
                    requestMsg.Content = new StringContent(requestContent);
                    requestMsg.Content.Headers.ContentType.MediaType = "application/json";

                    return(requestMsg);
                })).Response;

                // Get XASU token with MSA token
                response.EnsureSuccessStatusCode();
                Log.WriteLog("Fetch XSTS token succeeded.");

                token = await response.Content.DeserializeJsonAsync <XasTokenResponse>();
            }

            string key = AuthTokenCache.GetCacheKey(this.AuthContext.UserName, this.AuthContext.AccountSource, this.AuthContext.Tenant, string.Empty, sandbox);

            this.XTokenCache.Value.UpdateToken(key, token);

            return(token);
        }