예제 #1
0
        /// <summary>
        /// Uploads a file to the given path using the Windows Phone BackgroundTransferService.
        /// </summary>
        /// <param name="path">The path to the folder to upload the file to.</param>
        /// <param name="uploadLocation">The location of the file on the device to upload.</param>
        /// <param name="option">an enum to specify the overwrite behavior if a file with the same name already exists.</param>
        /// <param name="ct">a token that is used to cancel the background upload operation.</param>
        /// <param name="progress">an object that is called to report the background upload's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveOperationResult> BackgroundUploadAsync(
            string path,
            Uri uploadLocation,
            OverwriteOption option,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (path == null)
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UrlInvalid"),
                                               "path");
                throw new ArgumentNullException("path", message);
            }

            if (uploadLocation == null)
            {
                throw new ArgumentNullException("uploadLocation");
            }

            string filename = Path.GetFileName(uploadLocation.OriginalString);

            if (string.IsNullOrEmpty(filename))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMissingFileName"),
                                               "uploadLocation");
                throw new ArgumentException(message, "uploadLocation");
            }

            if (!BackgroundTransferHelper.IsRootedInSharedTransfers(uploadLocation))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMustBeRootedInSharedTransfers"),
                                               "uploadLocation");
                throw new ArgumentException(message, "uploadLocation");
            }

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            var builder = new BackgroundUploadOperation.Builder
            {
                BackgroundTransferService = this.BackgroundTransferService,
                Client = this,
                Path   = path,
                UploadLocationOnDevice = uploadLocation,
                OverwriteOption        = option,
                Progress = progress,
                BackgroundTransferPreferences = this.BackgroundTransferPreferences
            };

            BackgroundUploadOperation operation = builder.Build();

            ct.Register(operation.Cancel);

            return(operation.ExecuteAsync());
        }
        internal Task <LiveDownloadOperationResult> InternalDownloadAsync(string path, IFileSource destination, IBackgroundTransferProvider btu, CancellationToken ct, IProgress <LiveOperationProgress> progress)
        {
            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            var tcs = new TaskCompletionSource <LiveDownloadOperationResult>();

            var op = btu.GetDownloadOperation(this, this.GetResourceUri(path, ApiMethod.Download), destination, progress, syncContext);

            op.OperationCompletedCallback = (LiveDownloadOperationResult result) =>
            {
                if (result.IsCancelled)
                {
                    tcs.TrySetCanceled();
                }
                else if (result.Error != null)
                {
                    tcs.TrySetException(result.Error);
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            };

            ct.Register(op.Cancel);

            op.Execute();

            return(tcs.Task);
        }
        private Task <LiveOperationResult> ExecuteApiOperation(ApiOperation op, CancellationToken ct)
        {
            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            var tcs = new TaskCompletionSource <LiveOperationResult>();

            op.OperationCompletedCallback = (LiveOperationResult opResult) =>
            {
                if (opResult.IsCancelled)
                {
                    tcs.TrySetCanceled();
                }
                else if (opResult.Error != null)
                {
                    tcs.TrySetException(opResult.Error);
                }
                else
                {
                    tcs.TrySetResult(opResult);
                }
            };

            ct.Register(op.Cancel);

            op.Execute();

            return(tcs.Task);
        }
예제 #4
0
        private void OnAuthFlowEnded(string resultData)
        {
            if (this.rootVisual != null)
            {
                this.rootVisual.Navigating -= OnRootNavigating;
            }

            if (this.rootPage != null)
            {
                this.rootPage.BackKeyPress -= OnBackKeyPress;
            }

            if (this.callback != null)
            {
                if (!string.IsNullOrEmpty(resultData))
                {
                    this.callback(resultData, null);
                }
                else
                {
                    var error = new LiveAuthException(
                        AuthErrorCodes.AccessDenied,
                        ResourceHelper.GetString("ConsentNotGranted"));
                    this.callback(null, error);
                }
            }
        }
        public Task <LiveOperationResult> UploadAsync(string path, IFileSource fileSource, OverwriteOption option, IBackgroundTransferProvider btu, CancellationToken ct, IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"),
                                        "path"));
            }

            if (null == fileSource)
            {
                throw new ArgumentNullException(
                          "fileSource",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullParameter"),
                                        "fileSource"));
            }

            if (null != fileSource && string.IsNullOrEmpty(fileSource.Filename))
            {
                throw new ArgumentException(
                          "fileName",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullOrEmptyParameter"),
                                        "fileName"));
            }

            if (null == btu)
            {
                btu = new Microsoft.Live.Transfers.BasicTransferProvider();
            }

            ApiOperation op = btu.GetUploadOperation(this, this.GetResourceUri(path, ApiMethod.Upload), fileSource, option, progress, syncContext);

            return(this.ExecuteApiOperation(op, ct));
        }
예제 #6
0
        /// <summary>
        /// Processes authentication result from the server.
        /// Method could return synchronously or asynchronously.
        /// </summary>
        private void ProcessAuthResponse(string responseData, Action <LiveLoginResult> callback)
        {
            if (string.IsNullOrEmpty(responseData))
            {
                // non-connected user scenario. return status unknown.
                callback(new LiveLoginResult(LiveConnectSessionStatus.Unknown, null));
                return;
            }

            Uri responseUrl;

            try
            {
                responseUrl = new Uri(responseData, UriKind.Absolute);
            }
            catch (FormatException)
            {
                callback(new LiveLoginResult(
                             new LiveAuthException(AuthErrorCodes.ServerError, ResourceHelper.GetString("ServerError"))));
                return;
            }

            if (!string.IsNullOrEmpty(responseUrl.Fragment))
            {
                callback(this.ParseResponseFragment(responseUrl.Fragment));
                return;
            }

            if (!string.IsNullOrEmpty(responseUrl.Query))
            {
                IDictionary <string, object> parameters = LiveAuthClient.ParseQueryString(responseUrl.Query);
                if (parameters.ContainsKey(AuthConstants.Code))
                {
                    var authCode = parameters[AuthConstants.Code] as string;
                    if (!string.IsNullOrEmpty(authCode))
                    {
                        var refreshOp = new RefreshTokenOperation(
                            this,
                            this.clientId,
                            authCode,
                            this.redirectUri,
                            this.syncContext);

                        refreshOp.OperationCompletedCallback = callback;
                        refreshOp.Execute();

                        return;
                    }
                }
                else if (parameters.ContainsKey(AuthConstants.Error))
                {
                    callback(GetErrorResult(parameters));
                    return;
                }
            }

            callback(
                new LiveLoginResult(
                    new LiveAuthException(AuthErrorCodes.ServerError, ResourceHelper.GetString("ServerError"))));
        }
예제 #7
0
        private ApiOperation GetApiOperation(string path, ApiMethod method, string body)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException("path");
            }

            if (IsAbsolutePath(path))
            {
                throw new ArgumentException(
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("RelativeUrlRequired"), "path"),
                          "path");
            }

            Uri apiUri = this.GetResourceUri(path, method);

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            ApiOperation operation = null;

            switch (method)
            {
            case ApiMethod.Get:
            case ApiMethod.Delete:
                operation = new ApiOperation(this, apiUri, method, null, null);
                break;

            case ApiMethod.Post:
            case ApiMethod.Put:
            case ApiMethod.Copy:
            case ApiMethod.Move:
                if (body == null)
                {
                    throw new ArgumentNullException("body");
                }

                if (string.IsNullOrWhiteSpace(body))
                {
                    throw new ArgumentException("body");
                }

                operation = new ApiWriteOperation(this, apiUri, method, body, null);
                break;

            default:
                Debug.Assert(false, "method not suppported.");
                break;
            }

            return(operation);
        }
예제 #8
0
        /// <summary>
        /// Upload a file to the server.
        /// </summary>
        /// <param name="path">relative or absolute uri to the location where the file should be uploaded to.</param>
        /// <param name="fileName">name for the uploaded file.</param>
        /// <param name="inputStream">Stream that contains the file content.</param>
        /// <param name="option">
        ///     a enum to specify the overwrite behavior if a file with the same name already exists.
        ///     Default is DoNotOverwrite.
        /// </param>
        /// <param name="ct">a cancellation token</param>
        /// <param name="progress">a progress event callback handler</param>
        public Task <LiveOperationResult> UploadAsync(
            string path,
            string fileName,
            Stream inputStream,
            OverwriteOption option,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            LiveUtility.ValidateNotNullOrWhiteSpaceString(path, "path");
            LiveUtility.ValidateNotNullParameter(inputStream, "inputStream");

            if (string.IsNullOrEmpty(fileName))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("InvalidNullOrEmptyParameter"),
                                               "fileName");
                throw new ArgumentException(message, "fileName");
            }

            if (!inputStream.CanRead)
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("StreamNotReadable"),
                                               "inputStream");
                throw new ArgumentException(message, "inputStream");
            }

            var tcs = new TaskCompletionSource <LiveOperationResult>();
            var op  = new UploadOperation(
                this,
                this.GetResourceUri(path, ApiMethod.Upload),
                fileName,
                inputStream,
                option,
                progress,
                null);

            op.OperationCompletedCallback = (LiveOperationResult result) =>
            {
                if (result.IsCancelled)
                {
                    tcs.TrySetCanceled();
                }
                else if (result.Error != null)
                {
                    tcs.TrySetException(result.Error);
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            };

            ct.Register(op.Cancel);
            op.Execute();

            return(tcs.Task);
        }
예제 #9
0
        /// <summary>
        /// Logs user out of the application.  Clears any cached Session data.
        /// </summary>
        public void Logout()
        {
            if (!this.CanLogout)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("CantLogout"));
            }

            this.AuthClient.CloseSession();
        }
예제 #10
0
        /// <summary>
        /// Creates a new instance of the auth client.
        /// <param name="clientId">Client id of the application.</param>
        /// </summary>
        public LiveAuthClient(string clientId)
        {
            if (string.IsNullOrEmpty(clientId))
            {
                throw new ArgumentException(
                          string.Format(ResourceHelper.GetString("InvalidNullParameter"), "clientId"), "clientId");
            }

            this.AuthClient = new PhoneAuthClient(this);
            this.InitializeMembers(clientId, null);
        }
예제 #11
0
        /// <summary>
        /// Upload a file to the server.
        /// </summary>
        /// <param name="path">relative or absolute uri to the location where the file should be uploaded to.</param>
        /// <param name="fileName">name for the uploaded file.</param>
        /// <param name="inputStream">Stream that contains the file content.</param>
        /// <param name="option">an enum to specify the overwrite behavior if a file with the same name already exists.</param>
        /// <param name="ct">a token that is used to cancel the upload operation.</param>
        /// <param name="progress">an object that is called to report the upload's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveOperationResult> UploadAsync(
            string path,
            string fileName,
            Stream inputStream,
            OverwriteOption option,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrEmpty(path))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UrlInvalid"),
                                               "path");
                throw new ArgumentException(message, "path");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("InvalidNullOrEmptyParameter"),
                                               "fileName");
                throw new ArgumentException(message, "fileName");
            }

            if (inputStream == null)
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("InvalidNullParameter"),
                                               "inputStream");
                throw new ArgumentNullException("inputStream", message);
            }

            if (!inputStream.CanRead)
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("StreamNotReadable"),
                                               "inputStream");
                throw new ArgumentException(message, "inputStream");
            }

            var operation = new UploadOperation(
                this,
                this.GetResourceUri(path, ApiMethod.Upload),
                fileName,
                inputStream,
                option,
                progress != null ? new Action <LiveOperationProgress>(progress.Report) : null,
                SynchronizationContextWrapper.Current);

            return(this.ExecuteApiOperation(operation, ct));
        }
예제 #12
0
        /// <summary>
        /// Download a file into a stream.
        /// </summary>
        /// <param name="path">relative or absolute uri to the file to be downloaded.</param>
        /// <param name="ct">a token that is used to cancel the download operation.</param>
        /// <param name="progress">an object that is called to report the download's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveDownloadOperationResult> DownloadAsync(
            string path,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrEmpty(path))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UrlInvalid"),
                                               "path");
                throw new ArgumentException(message, "path");
            }

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            var tcs       = new TaskCompletionSource <LiveDownloadOperationResult>();
            var operation = new DownloadOperation(
                this,
                this.GetResourceUri(path, ApiMethod.Download),
                progress != null ? new Action <LiveOperationProgress>(progress.Report) : null,
                SynchronizationContextWrapper.Current)
            {
                OperationCompletedCallback = (LiveDownloadOperationResult result) =>
                {
                    if (result.IsCancelled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else if (result.Error != null)
                    {
                        tcs.TrySetException(result.Error);
                    }
                    else
                    {
                        tcs.TrySetResult(result);
                    }
                }
            };

            ct.Register(operation.Cancel);

            operation.Execute();

            return(tcs.Task);
        }
예제 #13
0
        /// <summary>
        /// Ensures that only one async operation is active at any time.
        /// </summary>
        private void PrepareForAsync()
        {
            Debug.Assert(
                this.asyncInProgress == 0 || this.asyncInProgress == 1,
                "Unexpected value for 'asyncInProgress' field.");

            if (this.asyncInProgress > 0)
            {
                throw new LiveAuthException(
                          AuthErrorCodes.ClientError,
                          ResourceHelper.GetString("AsyncOperationInProgress"));
            }

            Interlocked.Increment(ref this.asyncInProgress);

            this.syncContext = SynchronizationContextWrapper.Current;
        }
예제 #14
0
        /// <summary>
        /// Creates a new instance of the auth client.
        /// The application client id is the same as the application package sid.
        /// </summary>
        /// <param name="redirectUri">The application's redirect uri as specified in application management portal.</param>
        public LiveAuthClient(string redirectUri)
        {
            if (!string.IsNullOrEmpty(redirectUri) && !IsValidRedirectDomain(redirectUri))
            {
                throw new ArgumentException(
                          redirectUri,
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "redirectUri"));
            }

            this.AuthClient = new TailoredAuthClient(this);

            if (string.IsNullOrEmpty(redirectUri))
            {
                redirectUri = TailoredAuthClient.Win8ReturnUriScheme;
            }

            this.InitializeMembers(string.Empty, redirectUri);
        }
예제 #15
0
        /// <summary>
        /// Upload a stream to the server.
        /// </summary>
        /// <param name="path">relative or absolute uri to the location where the file should be uploaded to.</param>
        /// <param name="fileName">name for the uploaded file.</param>
        /// <param name="inputStream">Stream that contains the upload's content.</param>
        /// <param name="option">an enum to specify the overwrite behavior if a file with the same name already exists.</param>
        /// <param name="ct">a token that is used to cancel the upload operation.</param>
        /// <param name="progress">an object that is called to report the upload's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveOperationResult> BackgroundUploadAsync(
            string path,
            string fileName,
            IInputStream inputStream,
            OverwriteOption option,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"),
                                        "path"));
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException(
                          "fileName",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullOrEmptyParameter"),
                                        "fileName"));
            }

            if (inputStream == null)
            {
                throw new ArgumentNullException(
                          "inputStream",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullParameter"),
                                        "inputStream"));
            }

            ApiOperation op =
                new TailoredUploadOperation(
                    this,
                    this.GetResourceUri(path, ApiMethod.Upload),
                    fileName,
                    inputStream,
                    option,
                    progress,
                    null);

            return(this.ExecuteApiOperation(op, ct));
        }
예제 #16
0
        /// <summary>
        /// Download a file into a stream.
        /// </summary>
        /// <param name="path">relative or absolute uri to the file to be downloaded.</param>
        /// <param name="ct">a token that is used to cancel the upload operation.</param>
        /// <param name="progress">an object that is called to report the download's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveDownloadOperationResult> BackgroundDownloadAsync(
            string path,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "path"));
            }

            return(this.InternalDownloadAsync(path, null, ct, progress));
        }
예제 #17
0
        /// <summary>
        /// Creates a new instance of the auth client.
        /// The application client id is the same as the application package sid.
        /// </summary>
        /// <param name="redirectUri">The application's redirect uri as specified in application management portal.</param>
        public LiveAuthClient(string redirectUri)
        {
            if (!string.IsNullOrEmpty(redirectUri) && !IsValidRedirectDomain(redirectUri))
            {
                throw new ArgumentException(
                          redirectUri,
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "redirectUri"));
            }

            this.AuthClient = new TailoredAuthClient(this);

            string appId = this.GetAppPackageSid();

            if (string.IsNullOrEmpty(redirectUri))
            {
                redirectUri = appId;
            }

            this.InitializeMembers(appId.TrimEnd('/'), redirectUri);
        }
        public Task <LiveDownloadOperationResult> DownloadAsync(string path, IBackgroundTransferProvider btu, CancellationToken ct, IProgress <LiveOperationProgress> progress)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "path"));
            }

            if (null == btu)
            {
                btu = new Microsoft.Live.Transfers.BasicTransferProvider();
            }

            return(this.InternalDownloadAsync(path, null, btu, ct, progress));
        }
예제 #19
0
        internal Uri GetResourceUri(string path, ApiMethod method)
        {
            try
            {
                if ((path.StartsWith("https://", StringComparison.OrdinalIgnoreCase) &&
                     !path.StartsWith(this.ApiEndpoint, StringComparison.OrdinalIgnoreCase)) ||
                    path.StartsWith("http://", StringComparison.OrdinalIgnoreCase))
                {
                    return(new Uri(path, UriKind.Absolute));
                }

                StringBuilder sb;
                if (path.StartsWith(this.ApiEndpoint, StringComparison.OrdinalIgnoreCase))
                {
                    sb = new StringBuilder(path);
                }
                else
                {
                    sb = new StringBuilder(this.ApiEndpoint);
                    sb = sb.AppendUrlPath(path);
                }

                var resourceUrl = new Uri(sb.ToString(), UriKind.Absolute);
                sb.Append(string.IsNullOrEmpty(resourceUrl.Query) ? "?" : "&");

                if (method != ApiMethod.Download)
                {
                    sb.AppendQueryParam(QueryParameters.SuppressResponseCodes, "true");
                    sb.Append("&").AppendQueryParam(QueryParameters.SuppressRedirects, "true");
                }

                return(new Uri(sb.ToString(), UriKind.Absolute));
            }
            catch (FormatException)
            {
                throw new ArgumentException(
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "path"),
                          "path");
            }
        }
        /// <summary>
        /// Download a file into a stream.
        /// </summary>
        /// <param name="path">relative or absolute uri to the file to be downloaded.</param>
        /// <param name="ct">a cancellation token</param>
        /// <param name="progress">a progress event callback handler</param>
        public Task <LiveDownloadOperationResult> DownloadAsync(
            string path,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            LiveUtility.ValidateNotNullOrWhiteSpaceString(path, "path");

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            var tcs = new TaskCompletionSource <LiveDownloadOperationResult>();
            var op  = new DownloadOperation(
                this,
                this.GetResourceUri(path, ApiMethod.Download),
                progress,
                null);

            op.OperationCompletedCallback = (LiveDownloadOperationResult result) =>
            {
                if (result.IsCancelled)
                {
                    tcs.TrySetCanceled();
                }
                else if (result.Error != null)
                {
                    tcs.TrySetException(result.Error);
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            };

            ct.Register(op.Cancel);
            op.Execute();

            return(tcs.Task);
        }
        /// <summary>
        /// Creates a background upload operation.
        /// </summary>
        /// <param name="path">relative or absolute uri to the location where the file should be uploaded to.</param>
        /// <param name="fileName">name for the uploaded file.</param>
        /// <param name="inputStream">Stream that contains the upload's content.</param>
        /// <param name="option">an enum to specify the overwrite behavior if a file with the same name already exists.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveUploadOperation> CreateBackgroundUploadAsync(
            string path,
            string fileName,
            IInputStream inputStream,
            OverwriteOption option)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"),
                                        "path"));
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException(
                          "fileName",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullOrEmptyParameter"),
                                        "fileName"));
            }

            if (inputStream == null)
            {
                throw new ArgumentNullException(
                          "inputStream",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullParameter"),
                                        "inputStream"));
            }

            var op = new CreateBackgroundUploadOperation(
                this,
                this.GetResourceUri(path, ApiMethod.Upload),
                fileName,
                inputStream,
                option);

            return(op.ExecuteAsync());
        }
        public Task <LiveDownloadOperationResult> DownloadAsync(string path, IFileSource destination, IBackgroundTransferProvider btu = null, IProgress <LiveOperationProgress> progress = null)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentException(
                          "path",
                          String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "path"));
            }

            if (null == destination)
            {
                throw new ArgumentNullException("destination",
                                                String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullParameter"), "destination"));
            }

            return(this.InternalDownloadAsync(path, destination, btu, new CancellationToken(false), progress));
        }
예제 #23
0
        /// <summary>
        /// Process the error response.
        /// </summary>
        private async Task <Exception> ProcessDownloadErrorResponse(Exception exception)
        {
            Exception error;

            try
            {
                IInputStream responseStream = this.downloadOperation.GetResultStreamAt(0);
                if (responseStream == null)
                {
                    error = new LiveConnectException(
                        ApiOperation.ApiServerErrorCode,
                        ResourceHelper.GetString("ConnectionError"));
                }
                else
                {
                    var  reader = new DataReader(responseStream);
                    uint length = await reader.LoadAsync(MaxDownloadResponseLength);

                    error = ApiOperation.CreateOperationResultFrom(reader.ReadString(length), ApiMethod.Download).Error;
                    if (error is FormatException)
                    {
                        // if we cannot understand the error response,
                        // return the exception thrown by the background downloader.
                        error = exception;
                    }
                }
            }
            catch (COMException exp)
            {
                error = exp;
            }
            catch (FileNotFoundException exp)
            {
                error = exp;
            }

            return(error);
        }
예제 #24
0
        /// <summary>
        /// Displays the login/consent UI and returns a Session object when user completes the auth flow.
        /// </summary>
        /// <param name="scopes">The list of offers that the application is requesting user consent for.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public async Task <LiveLoginResult> LoginAsync(IEnumerable <string> scopes)
        {
            if (scopes == null && this.scopes == null)
            {
                throw new ArgumentNullException("scopes");
            }

            if (scopes != null)
            {
                this.scopes = new List <string>(scopes);
            }

            bool onUiThread = Deployment.Current.CheckAccess();

            if (!onUiThread)
            {
                throw new InvalidOperationException(
                          string.Format(ResourceHelper.GetString("NotOnUiThread"), "LoginAsync"));
            }

            this.PrepareForAsync();

            return(await this.AuthenticateAsync(false /* silent flow */));
        }
예제 #25
0
        /// <summary>
        /// Download a file to disk.
        /// </summary>
        /// <param name="path">relative or absolute uri to the file to be downloaded.</param>
        /// <param name="outputFile">the file that the downloaded content is written to.</param>
        /// <param name="ct">a token that is used to cancel the download operation.</param>
        /// <param name="progress">an object that is called to report the download's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public Task <LiveDownloadOperationResult> BackgroundDownloadAsync(
            string path,
            IStorageFile outputFile,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException("path",
                                            String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("UrlInvalid"), "path"));
            }

            if (outputFile == null)
            {
                throw new ArgumentNullException("outputFile",
                                                String.Format(CultureInfo.CurrentUICulture, ResourceHelper.GetString("InvalidNullParameter"), "outputFile"));
            }

            return(this.InternalDownloadAsync(path, outputFile, ct, progress));
        }
        /// <summary>
        /// Authenticate the user.  Ask user for consent if neccessary.
        /// </summary>
        public async Task <LiveLoginResult> AuthenticateAsync(string scopes, bool silent)
        {
            Exception error               = null;
            string    accessToken         = null;
            string    authenticationToken = null;

            LiveLoginResult result = null;

            try
            {
                accessToken = await this.GetAccessToken(scopes, silent);

                LiveConnectSession session = new LiveConnectSession(this.authClient);
                session.AccessToken = accessToken;

                if (!string.IsNullOrEmpty(this.authClient.RedirectUrl) &&
                    !this.authClient.RedirectUrl.StartsWith(Win8AppIdPrefix, StringComparison.OrdinalIgnoreCase))
                {
                    authenticationToken = await this.GetAuthenticationToken(this.authClient.RedirectUrl, silent);

                    session.AuthenticationToken = authenticationToken;
                }

                result = new LiveLoginResult(LiveConnectSessionStatus.Connected, session);
            }
            catch (TaskCanceledException)
            {
                result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
            }
            catch (Exception comExp)
            {
                switch (comExp.HResult)
                {
                case TailoredAuthClient.UserNotFoundLoginExceptionHResult:
                    result = new LiveLoginResult(LiveConnectSessionStatus.Unknown, null);
                    break;

                case TailoredAuthClient.ConsentNotGrantedExceptionHResult:
                    result = new LiveLoginResult(LiveConnectSessionStatus.NotConnected, null);
                    break;

                case TailoredAuthClient.InvalidClientExceptionHResult:
                case TailoredAuthClient.InvalidAuthTargetExceptionHResult:
                    error = new LiveAuthException(AuthErrorCodes.InvalidRequest, ResourceHelper.GetString("InvalidAuthClient"), comExp);
                    break;

                default:
                    error = new LiveAuthException(AuthErrorCodes.ServerError, ResourceHelper.GetString("ServerError"), comExp);
                    break;
                }
            }

            if (result == null)
            {
                Debug.Assert(error != null);

                result = new LiveLoginResult(error);
            }

            return(result);
        }
예제 #27
0
        /// <summary>
        /// Downloads the resource with the given path to the downloadLocation using the Windows Phone
        /// BackgroundTransferService.
        /// </summary>
        /// <param name="path">Path to the resource to download</param>
        /// <param name="downloadLocation">
        ///     The path to the file that will contain the download resource.
        ///     The downloadLocation must exist in /shared/transfers.
        /// </param>
        /// <param name="ct">a token that is used to cancel the background download operation.</param>
        /// <param name="progress">an object that is called to report the background download's progress.</param>
        /// <returns>A Task object representing the asynchronous operation.</returns>
        public async Task <LiveOperationResult> BackgroundDownloadAsync(
            string path,
            Uri downloadLocation,
            CancellationToken ct,
            IProgress <LiveOperationProgress> progress)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UrlInvalid"),
                                               "path");
                if (path == null)
                {
                    throw new ArgumentNullException("path", message);
                }

                throw new ArgumentException(message, "path");
            }

            if (downloadLocation == null)
            {
                throw new ArgumentNullException("downloadLocation");
            }

            string filename = Path.GetFileName(downloadLocation.OriginalString);

            if (string.IsNullOrEmpty(filename))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMissingFileName"),
                                               "downloadLocation");
                throw new ArgumentException(message, "downloadLocation");
            }

            if (!BackgroundTransferHelper.IsRootedInSharedTransfers(downloadLocation))
            {
                string message = String.Format(CultureInfo.CurrentUICulture,
                                               ResourceHelper.GetString("UriMustBeRootedInSharedTransfers"),
                                               "downloadLocation");
                throw new ArgumentException(message, "downloadLocation");
            }

            if (this.Session == null)
            {
                throw new LiveConnectException(ApiOperation.ApiClientErrorCode, ResourceHelper.GetString("UserNotLoggedIn"));
            }

            Uri requestUri = this.GetResourceUri(path, ApiMethod.Download);

            var builder = new BackgroundDownloadOperation.Builder
            {
                RequestUri = requestUri,
                DownloadLocationOnDevice  = downloadLocation,
                BackgroundTransferService = this.BackgroundTransferService,
                Progress = progress,
                BackgroundTransferPreferences = this.BackgroundTransferPreferences
            };

            if (!this.Session.IsValid)
            {
                LiveLoginResult result = await this.Session.AuthClient.RefreshTokenAsync();

                if (result.Status == LiveConnectSessionStatus.Connected)
                {
                    this.Session = result.Session;
                }
            }

            builder.AccessToken = this.Session.AccessToken;

            BackgroundDownloadOperation operation = builder.Build();

            ct.Register(operation.Cancel);

            return(await operation.ExecuteAsync());
        }
예제 #28
0
        /// <summary>
        /// Initialize and invoke the login dialog
        /// </summary>
        /// <param name="clientId">The client id of the application.</param>
        /// <param name="scopes">The scopes that the application needs user consent for.</param>
        /// <param name="silent">True if authentication should be done w/ no UI.</param>
        /// <param name="callback">The callback function to be invoked when login completes.</param>
        public void AuthenticateAsync(string clientId, string scopes, bool silent, Action <string, Exception> callback)
        {
            this.callback = callback;

            if (silent)
            {
                // Silent flow not supported on phone.
                if (callback != null)
                {
                    ThreadPool.QueueUserWorkItem(
                        (object state) =>
                    {
                        callback(GenerateUserUnknownResponse(this.liveAuthClient.RedirectUrl), null);
                    });
                }

                return;
            }

            if (this.popup != null)
            {
                throw new InvalidOperationException(ResourceHelper.GetString("LoginPopupAlreadyOpen"));
            }

            string consentUrl = this.liveAuthClient.BuildLoginUrl(scopes, false);

            var rootVisual = Application.Current.RootVisual as PhoneApplicationFrame;

            Debug.Assert(rootVisual != null);

            if (rootVisual.RenderSize.Height <= 0)
            {
                throw new InvalidOperationException(ResourceHelper.GetString("RootVisualNotRendered"));
            }

            this.ClearAuthCookieIfNeeded(delegate()
            {
                if (this.IsSigningOut)
                {
                    // We are still signing out?! meaning we probably failed to connect to the network, then fail the request.
                    callback(
                        null,
                        new LiveAuthException(AuthErrorCodes.ClientError, ResourceHelper.GetString("ConnectionError")));
                    return;
                }

                // Store the application bar and remove from the page so it doesn't interfere with the popup login page.
                // It is restored when the popup closes.
                this.rootPage = rootVisual.Content as PhoneApplicationPage;
                if (this.rootPage != null)
                {
                    this.appBar = rootPage.ApplicationBar;
                    this.rootPage.ApplicationBar = null;
                }

                var loginPage = new LoginPage(consentUrl, this.liveAuthClient.RedirectUrl, this.OnLoginPageCompleted);

                int offset = 0;
                if (SystemTray.IsVisible)
                {
                    offset = PhoneAuthClient.RenderSizeOffset;
                }
                offset     = (rootVisual.RenderSize.Height >= offset) ? offset : 0;
                this.popup = new Popup()
                {
                    Child          = loginPage,
                    VerticalOffset = offset,
                    Height         = Application.Current.RootVisual.RenderSize.Height - offset,
                    IsOpen         = true
                };
            });
        }
예제 #29
0
        private async Task <LiveOperationResult> ExecuteAsync(bool start, CancellationToken cancellationToken, IProgress <LiveOperationProgress> progressHandler)
        {
            LiveOperationResult opResult;
            Exception           error = null;

            try
            {
                var progressHandlerWrapper = new Progress <UploadOperation>(t =>
                {
                    if (progressHandler != null)
                    {
                        progressHandler.Report(
                            new LiveOperationProgress(
                                (long)t.Progress.BytesSent,       //uploading, not downloading
                                (long)t.Progress.TotalBytesToSend //uploading, not downloading
                                ));
                    }
                });

                IAsyncOperationWithProgress <UploadOperation, UploadOperation> asyncOperation = start ? this.uploadOperation.StartAsync() : this.uploadOperation.AttachAsync();
                await asyncOperation.AsTask(cancellationToken, progressHandlerWrapper);
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception exp)
            {
                // This might be an server error. We will read the response to determine the error message.
                error = exp;
            }

            IInputStream responseStream = this.uploadOperation.GetResultStreamAt(0);

            if (responseStream == null)
            {
                throw new LiveConnectException(
                          ApiOperation.ApiClientErrorCode,
                          ResourceHelper.GetString("ConnectionError"));
            }
            else
            {
                var  reader = new DataReader(responseStream);
                uint length = await reader.LoadAsync(MaxUploadResponseLength);

                opResult = ApiOperation.CreateOperationResultFrom(reader.ReadString(length), ApiMethod.Upload);

                if (opResult.Error != null)
                {
                    if (opResult.Error is LiveConnectException)
                    {
                        throw opResult.Error;
                    }
                    else if (error != null)
                    {
                        // If the error did not come from the api service,
                        // we'll just return the error thrown by the uploader.
                        throw error;
                    }
                }

                return(opResult);
            }
        }