/// <summary>
        /// Initializes a new instance of the MobileServiceClient class.
        /// </summary>
        /// <param name="mobileAppUri">
        /// Absolute URI of the Microsoft Azure Mobile App.
        /// </param>
        /// <param name="handlers">
        /// Chain of <see cref="HttpMessageHandler" /> instances.
        /// All but the last should be <see cref="DelegatingHandler"/>s.
        /// </param>
        public MobileServiceClient(Uri mobileAppUri,
                                   params HttpMessageHandler[] handlers)
        {
            if (mobileAppUri == null)
            {
                throw new ArgumentNullException("mobileAppUri");
            }

            if (mobileAppUri.IsAbsoluteUri)
            {
                // Trailing slash in the MobileAppUri is important. Fix it right here before we pass it on further.
                this.MobileAppUri = new Uri(MobileServiceUrlBuilder.AddTrailingSlash(mobileAppUri.AbsoluteUri), UriKind.Absolute);
            }
            else
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.InvariantCulture, Resources.MobileServiceClient_NotAnAbsoluteURI, mobileAppUri),
                          "mobileAppUri");
            }

            this.InstallationId = GetApplicationInstallationId();

            handlers          = handlers ?? EmptyHttpMessageHandlers;
            this.HttpClient   = new MobileServiceHttpClient(handlers, this.MobileAppUri, this.InstallationId);
            this.Serializer   = new MobileServiceSerializer();
            this.EventManager = new MobileServiceEventManager();
            this.SyncContext  = new MobileServiceSyncContext(this);
        }
        /// <summary>
        /// Helper function to assemble the Uri for a given custom api.
        /// </summary>
        /// <param name="apiName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private string CreateAPIUriString(string apiName, IDictionary <string, string> parameters = null)
        {
            string uriFragment = apiName.StartsWith("/") ? apiName : string.Format(CultureInfo.InvariantCulture, "api/{0}", apiName);
            string queryString = MobileServiceUrlBuilder.GetQueryString(parameters, useTableAPIRules: false);

            return(MobileServiceUrlBuilder.CombinePathAndQuery(uriFragment, queryString));
        }
Beispiel #3
0
        /// <summary>
        /// Excutes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will return with results when the query finishes.
        /// </returns>
        public async Task <JToken> ReadAsync(string query, IDictionary <string, string> parameters)
        {
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath          = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, this.MobileServiceClient.CurrentUser, null, true);

            return(response.Content.ParseToJToken(this.MobileServiceClient.SerializerSettings));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MobileServiceAuthentication"/> class.
        /// </summary>
        /// <param name="client">
        /// The <see cref="MobileServiceClient"/> associated with this
        /// MobileServiceLogin instance.
        /// </param>
        /// <param name="providerName">
        /// The <see cref="MobileServiceAuthenticationProvider"/> used to authenticate.
        /// </param>
        /// <param name="parameters">
        /// Provider specific extra parameters that are sent as query string parameters to login endpoint.
        /// </param>
        public MobileServiceAuthentication(IMobileServiceClient client, string providerName, IDictionary <string, string> parameters)
        {
            Debug.Assert(client != null, "client should not be null.");
            if (providerName == null)
            {
                throw new ArgumentNullException("providerName");
            }

            this.Client       = client;
            this.Parameters   = parameters;
            this.ProviderName = providerName;
            string path = MobileServiceUrlBuilder.CombinePaths(LoginAsyncUriFragment, this.ProviderName);
            string loginAsyncDoneUriFragment = MobileServiceAuthentication.LoginAsyncDoneUriFragment;

            if (!string.IsNullOrEmpty(this.Client.LoginUriPrefix))
            {
                path = MobileServiceUrlBuilder.CombinePaths(this.Client.LoginUriPrefix, this.ProviderName);
                loginAsyncDoneUriFragment = MobileServiceUrlBuilder.CombinePaths(this.Client.LoginUriPrefix, "done");
            }
            string queryString  = MobileServiceUrlBuilder.GetQueryString(parameters, useTableAPIRules: false);
            string pathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, queryString);

            this.StartUri = new Uri(this.Client.MobileAppUri, pathAndQuery);
            this.EndUri   = new Uri(this.Client.MobileAppUri, loginAsyncDoneUriFragment);

            if (this.Client.AlternateLoginHost != null)
            {
                this.StartUri = new Uri(this.Client.AlternateLoginHost, pathAndQuery);
                this.EndUri   = new Uri(this.Client.AlternateLoginHost, loginAsyncDoneUriFragment);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Provides Login logic for an existing token.
        /// </summary>
        /// <returns>
        /// Task that will complete with the response string when the user has finished authentication.
        /// </returns>
        protected override Task <string> LoginAsyncOverride()
        {
            string path         = MobileServiceUrlBuilder.CombinePaths(MobileServiceAuthentication.LoginAsyncUriFragment, this.ProviderName);
            string queryString  = MobileServiceUrlBuilder.GetQueryString(this.Parameters);
            string pathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, queryString);

            return(client.HttpClient.RequestWithoutHandlersAsync(HttpMethod.Post, pathAndQuery, this.client.CurrentUser, token.ToString()));
        }
        /// <summary>
        /// Executes a lookup against a table.
        /// </summary>
        /// <param name="id">
        /// The id of the instance to lookup.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will return with a result when the lookup finishes.
        /// </returns>
        internal Task <string> SendLookupAsync(object id, IDictionary <string, string> parameters)
        {
            Debug.Assert(id != null);

            string uriFragment = MobileServiceUrlBuilder.GetUriFragment(this.TableName, id);
            string queryString = MobileServiceUrlBuilder.GetQueryString(parameters);
            string uriString   = MobileServiceUrlBuilder.CombinePathAndQuery(uriFragment, queryString);

            return(this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, null));
        }
        /// <summary>
        /// Inserts an <paramref name="instance"/> into the table.
        /// </summary>
        /// <param name="instance">
        /// The instance to insert into the table.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will complete when the insert finishes.
        /// </returns>
        internal Task <string> SendInsertAsync(string instance, IDictionary <string, string> parameters)
        {
            Debug.Assert(instance != null);

            string uriFragment = MobileServiceUrlBuilder.GetUriFragment(this.TableName);
            string queryString = MobileServiceUrlBuilder.GetQueryString(parameters);
            string uriString   = MobileServiceUrlBuilder.CombinePathAndQuery(uriFragment, queryString);

            return(this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Post, uriString, instance));
        }
        /// <summary>
        /// Returns a URI for the table, optional id and parameters.
        /// </summary>
        /// <param name="tableName">
        /// The name of the table.
        /// </param>
        /// <param name="id">
        /// The id of the instance.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A URI string.
        /// </returns>
        private static string GetUri(string tableName, object id = null, IDictionary <string, string> parameters = null)
        {
            Debug.Assert(!string.IsNullOrEmpty(tableName));

            string uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, tableName);

            if (id != null)
            {
                string idString = Uri.EscapeDataString(string.Format(CultureInfo.InvariantCulture, "{0}", id));
                uriPath = MobileServiceUrlBuilder.CombinePaths(uriPath, idString);
            }

            string queryString = MobileServiceUrlBuilder.GetQueryString(parameters);

            return(MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, queryString));
        }
        /// <summary>
        /// Provides Login logic for an existing token.
        /// </summary>
        /// <returns>
        /// Task that will complete with the response string when the user has finished authentication.
        /// </returns>
        protected override Task <string> LoginAsyncOverride()
        {
            string path = MobileServiceUrlBuilder.CombinePaths(LoginAsyncUriFragment, ProviderName);

            if (!string.IsNullOrEmpty(client.LoginUriPrefix))
            {
                path = MobileServiceUrlBuilder.CombinePaths(client.LoginUriPrefix, ProviderName);
            }
            string queryString  = MobileServiceUrlBuilder.GetQueryString(Parameters);
            string pathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, queryString);

            if (client.AlternateLoginHost != null)
            {
                return(client.AlternateAuthHttpClient.RequestWithoutHandlersAsync(HttpMethod.Post, pathAndQuery, client.CurrentUser, token.ToString()));
            }
            return(client.HttpClient.RequestWithoutHandlersAsync(HttpMethod.Post, pathAndQuery, client.CurrentUser, token.ToString()));
        }
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will return with results when the query finishes.
        /// </returns>
        internal virtual async Task <QueryResult> ReadAsync(string query, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            features   = this.AddRequestFeatures(features, parameters);
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath;
            Uri    uri;
            bool   absolute;

            if (HttpUtility.TryParseQueryUri(this.MobileServiceClient.ApplicationUri, query, out uri, out absolute))
            {
                if (absolute)
                {
                    features |= MobileServiceFeatures.ReadWithLinkHeader;
                }
                uriPath = HttpUtility.GetUriWithoutQuery(uri);
                query   = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            return(await ReadAsync(uriString, features));
        }
        public MobileServiceClient(Uri mobileAppUri, params HttpMessageHandler[] handlers)
        {
            Arguments.IsNotNull(mobileAppUri, nameof(mobileAppUri));
            if (mobileAppUri.IsAbsoluteUri)
            {
                // Trailing slash in the MobileAppUri is important. Fix it right here before we pass it on further.
                MobileAppUri = new Uri(MobileServiceUrlBuilder.AddTrailingSlash(mobileAppUri.AbsoluteUri), UriKind.Absolute);
            }
            else
            {
                throw new ArgumentException($"'{mobileAppUri}' is not an absolute Uri", nameof(mobileAppUri));
            }

            this.InstallationId = GetApplicationInstallationId();

            handlers ??= EmptyHttpMessageHandlers;
            this.HttpClient   = new MobileServiceHttpClient(handlers, this.MobileAppUri, this.InstallationId, httpRequestTimeout);
            this.Serializer   = new MobileServiceSerializer();
            this.EventManager = new MobileServiceEventManager();
            this.SyncContext  = new MobileServiceSyncContext(this);
        }
Beispiel #12
0
        /// <summary>
        /// Executes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <param name="features">
        /// Value indicating which features of the SDK are being used in this call. Useful for telemetry.
        /// </param>
        /// <returns>
        /// A task that will return with results when the query finishes.
        /// </returns>
        internal virtual async Task <QueryResult> ReadAsync(string query, IDictionary <string, string> parameters, MobileServiceFeatures features)
        {
            parameters = AddSystemProperties(this.SystemProperties, parameters);

            string uriPath;
            Uri    uri;

            if (Uri.TryCreate(query, UriKind.Absolute, out uri))
            {
                features |= MobileServiceFeatures.ReadWithLinkHeader;
                uriPath   = uri.GetComponents(UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped);
                query     = uri.Query;
            }
            else
            {
                uriPath = MobileServiceUrlBuilder.CombinePaths(TableRouteSeparatorName, this.TableName);
            }

            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriPath, query);

            features = AddQueryParametersFeature(features, parameters);

            return(await ReadAsync(uriString, features));
        }
        /// <summary>
        /// Login via OAuth 2.0 PKCE protocol.
        /// </summary>
        /// <returns></returns>
        protected sealed override async Task <string> LoginAsyncOverride()
        {
            // Show platform-specific login ui and care about handling authorization_code from callback via deep linking.
            var authorizationCode = await this.GetAuthorizationCodeAsync();

            // Send authorization_code and code_verifier via HTTPS request to complete the PKCE flow.
            var path = MobileServiceUrlBuilder.CombinePaths(LoginAsyncUriFragment, ProviderName);

            if (!string.IsNullOrEmpty(client.LoginUriPrefix))
            {
                path = MobileServiceUrlBuilder.CombinePaths(client.LoginUriPrefix, ProviderName);
            }
            path = MobileServiceUrlBuilder.CombinePaths(path, "token");
            var tokenParameters = Parameters != null ? new Dictionary <string, string>(Parameters) : new Dictionary <string, string>();

            tokenParameters.Add("authorization_code", authorizationCode);
            tokenParameters.Add("code_verifier", CodeVerifier);
            var queryString  = MobileServiceUrlBuilder.GetQueryString(tokenParameters);
            var pathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, queryString);
            var httpClient   = client.AlternateLoginHost == null ? client.HttpClient : client.AlternateAuthHttpClient;

            return(await httpClient.RequestWithoutHandlersAsync(HttpMethod.Get, pathAndQuery, null));
        }
        protected MobileServicePKCEAuthentication(MobileServiceClient client, string provider, string uriScheme, IDictionary <string, string> parameters)
            : base(client, provider, parameters)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }
            if (string.IsNullOrWhiteSpace(uriScheme))
            {
                throw new ArgumentException("uriScheme");
            }

            this.client       = client;
            this.CodeVerifier = GetCodeVerifier();
            this.CallbackUri  = new Uri(MobileServiceUrlBuilder.CombileSchemeAndPath(uriScheme, "easyauth.callback"));

            var path = MobileServiceUrlBuilder.CombinePaths(LoginAsyncUriFragment, this.ProviderName);

            if (!string.IsNullOrEmpty(this.Client.LoginUriPrefix))
            {
                path = MobileServiceUrlBuilder.CombinePaths(this.Client.LoginUriPrefix, this.ProviderName);
            }
            var loginParameters = parameters != null ? new Dictionary <string, string>(parameters) : new Dictionary <string, string>();

            loginParameters.Add("post_login_redirect_url", this.CallbackUri.AbsoluteUri);
            loginParameters.Add("code_challenge", GetSha256Hash(this.CodeVerifier));
            loginParameters.Add("code_challenge_method", "S256");
            loginParameters.Add("session_mode", "token");
            var loginQueryString  = MobileServiceUrlBuilder.GetQueryString(loginParameters, false);
            var loginPathAndQuery = MobileServiceUrlBuilder.CombinePathAndQuery(path, loginQueryString);

            this.LoginUri = new Uri(this.Client.MobileAppUri, loginPathAndQuery);
            if (this.Client.AlternateLoginHost != null)
            {
                this.LoginUri = new Uri(this.Client.AlternateLoginHost, loginPathAndQuery);
            }
        }
        /// <summary>
        /// Excutes a query against the table.
        /// </summary>
        /// <param name="query">
        /// A query to execute.
        /// </param>
        /// <param name="parameters">
        /// A dictionary of user-defined parameters and values to include in
        /// the request URI query string.
        /// </param>
        /// <returns>
        /// A task that will return with results when the query finishes.
        /// </returns>
        public async Task <JToken> ReadAsync(string query, IDictionary <string, string> parameters)
        {
            string uriFragment      = MobileServiceUrlBuilder.GetUriFragment(this.TableName);
            string parametersString = MobileServiceUrlBuilder.GetQueryString(parameters);

            // Concatenate the query and the user-defined query string parameters
            if (!string.IsNullOrEmpty(parametersString))
            {
                if (!string.IsNullOrEmpty(query))
                {
                    query += '&' + parametersString;
                }
                else
                {
                    query = parametersString;
                }
            }

            string uriString = MobileServiceUrlBuilder.CombinePathAndQuery(uriFragment, query);

            string response = await this.MobileServiceClient.HttpClient.RequestAsync(HttpMethod.Get, uriString, null);

            return(response.ParseToJToken());
        }