public override string GetAuthorizationUrl(Uri redirectTo)
            {
                // If the Resource ID is known, use it. Otherwise, get authorized to the discovery service, first.
                string resourceIdForAuthRequest = ResourceId ?? _discoveryServiceInfo.ResourceId;

                return(Office365CommonController.GetAuthorizationUrl(resourceIdForAuthRequest, redirectTo));
            }
 internal ExchangeServiceInfo()
 {
     // For Exchange, the resource ID and API Endpoint are static for the public O365 cloud.
     ResourceId  = "https://outlook.office365.com/";
     ApiEndpoint = "https://outlook.office365.com/ews/odata";
     AccessToken = Office365CommonController.GetAccessToken(ResourceId);
 }
 internal ActiveDirectoryServiceInfo()
 {
     // For Active Directory, the resource ID and API Endpoint are static for the public O365 cloud.
     ResourceId  = "https://graph.windows.net/";
     ApiEndpoint = "https://graph.windows.net";
     AccessToken = Office365CommonController.GetAccessToken(ResourceId);
 }
            internal DiscoveryServiceInfo()
            {
                // In this initial Preview release, you must use a temporary Resource ID for Service Discovery ("Microsoft.SharePoint").
                // TODO: If this Resource ID ceases to work, check for an updated value at http://go.microsoft.com/fwlink/?LinkID=392944
                ResourceId = "Microsoft.SharePoint";

                ApiEndpoint = "https://api.office.com/discovery/me";
                AccessToken = Office365CommonController.GetAccessToken(ResourceId);
            }
            internal static async Task <Office365ServiceInfo> CreateAsync()
            {
                // Attempt to build an Office365ServiceInfo object based on cached API endpoint & resource ID information:
                SharePointOneDriveServiceInfo info = new SharePointOneDriveServiceInfo
                {
                    ResourceId  = (string)Office365CommonController.GetFromCache("SharePointOneDriveResourceId"),
                    ApiEndpoint = (string)Office365CommonController.GetFromCache("SharePointOneDriveApiEndpoint")
                };

                // If the Resource ID and API Endpoint are not empty, then the cached information is sufficient:
                if (info.ResourceId != null && info.ApiEndpoint != null)
                {
                    info.AccessToken = Office365CommonController.GetAccessToken(info.ResourceId);
                    return(info);
                }

                // If did not return above, invoke the Discovery Service to obtain the resource ID and API endpoint:
                info._discoveryServiceInfo = new DiscoveryServiceInfo();

                // If no auth header is available for Discovery, return the info as is, with the missing
                //     access token (and possibly a missing ResourceId and ApiEndpoint as well). The caller will need
                //     to do an OAuth redirect anyway.
                if (!info._discoveryServiceInfo.HasValidAccessToken)
                {
                    return(info);
                }

                // If still here, discovery has enough information to obtain the SharePoint OneDrive endpoints:
                DiscoveryResult[] results = await info._discoveryServiceInfo.DiscoverServicesAsync();

                DiscoveryResult myFilesEndpoint = results.First(result => result.Capability == "MyFiles");

                // Update and cache the resource ID and API endpoint:
                info.ResourceId = myFilesEndpoint.ServiceResourceId;
                // NOTE: In the initial Preview release of Service Discovery, the "MyFiles" endpoint URL will always
                //     start with something like "https://contoso-my.sharepoint.com/personal/<username>_contoso_com/_api",
                //     but the path following "/_api" may change over time.  For consistency, it is safer to manually
                //     extract the root path, and then append a call for the location of the Documents folder:
                info.ApiEndpoint = myFilesEndpoint.ServiceEndpointUri.Substring(
                    0, myFilesEndpoint.ServiceEndpointUri.IndexOf("/_api", StringComparison.Ordinal)) +
                                   "/_api/web/getfolderbyserverrelativeurl('Documents')";
                Office365CommonController.SaveInCache("SharePointOneDriveResourceId", info.ResourceId);
                Office365CommonController.SaveInCache("SharePointOneDriveApiEndpoint", info.ApiEndpoint);
                info.AccessToken = Office365CommonController.GetAccessToken(info.ResourceId);
                return(info);
            }
            /// <summary>
            /// Returns information obtained via Discovery. Will throw an exception on error.
            /// </summary>
            internal async Task <DiscoveryResult[]> DiscoverServicesAsync()
            {
                // Create a URL for retrieving the data:
                string requestUrl = String.Format(CultureInfo.InvariantCulture,
                                                  "{0}/services",
                                                  ApiEndpoint);

                // Prepare the HTTP request:
                using (HttpClient client = new HttpClient())
                {
                    Func <HttpRequestMessage> requestCreator = () =>
                    {
                        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                        request.Headers.Add("Accept", "application/json;odata=verbose");
                        return(request);
                    };

                    // Send the request using a helper method, which will add an authorization header to the request,
                    // and automatically retry with a new token if the existing one has expired.
                    using (HttpResponseMessage response = await Office365CommonController.SendRequestAsync(
                               this, client, requestCreator))
                    {
                        // Read the response and deserialize the data:
                        string responseString = await response.Content.ReadAsStringAsync();

                        if (!response.IsSuccessStatusCode)
                        {
                            throw new Exception("Could not obtain discovery information. Service returned " +
                                                response.StatusCode + ":\n\n" + responseString);
                        }

                        // If successful, return the discovery results
                        return(JObject.Parse(responseString)["d"]["results"].ToObject <DiscoveryResult[]>());
                    }
                }
            }
 /// <summary>
 /// Returns a URL through which a user can be authorized to access Office 365 APIs.
 /// After the authorization is complete, the user will be redirected back to the URL
 ///     defined by the redirectTo parameter. This can be the same URL as the caller's URL
 ///     (e.g., Request.Url), or it can contain additional query-string parameters
 ///     (e.g., to restore state).
 /// </summary>
 public virtual string GetAuthorizationUrl(Uri redirectTo)
 {
     return(Office365CommonController.GetAuthorizationUrl(ResourceId, redirectTo));
 }