/// <summary> /// A method used to get the WOPI resource URL by specified user credentials. /// </summary> /// <param name="absoluteUrlOfResource">A parameter represents the absolute URL of normal resource which will be used to get a WOPI resource URL.</param> /// <param name="rootResourceType">A parameter indicating the WOPI root resource URL type will be return.</param> /// <param name="userName">A parameter represents the name of user whose associated token will be return in the WOPI resource URL.</param> /// <param name="password">A parameter represents the password of the user.</param> /// <param name="domain">A parameter represents the domain of the user.</param> /// <returns>A return value represents the WOPI resource URL, which can be used in MS-WOPI operations.</returns> public string GetWOPIRootResourceUrl(string absoluteUrlOfResource, WOPIRootResourceUrlType rootResourceType, string userName, string password, string domain) { #region Verify the parameter if (string.IsNullOrEmpty(absoluteUrlOfResource)) { throw new ArgumentNullException("absoluteUrlOfResource"); } if (string.IsNullOrEmpty(userName)) { throw new ArgumentNullException("userName"); } if (string.IsNullOrEmpty(password)) { throw new ArgumentNullException("password"); } if (string.IsNullOrEmpty(domain)) { throw new ArgumentNullException("domain"); } if (WOPIRootResourceUrlType.FileLevel != rootResourceType && WOPIRootResourceUrlType.FolderLevel != rootResourceType) { throw new NotSupportedException(string.Format(@"The test suite only supports [{0}] and [{1}] two WOPI root resource URL formats.", WOPIRootResourceUrlType.FileLevel, WOPIRootResourceUrlType.FolderLevel)); } #endregion string wopiResourceUrl = string.Empty; if (!WOPIResourceUrlCache.TryGetWOPIResourceUrl(userName, domain, absoluteUrlOfResource, out wopiResourceUrl)) { // Get the response by specified user credential this.Site.Log.Add( LogEntryKind.Debug, "Try to get the [{0}] type WOPI URL for resource:[{1}]\r\n User:[{2}]\\[{3}]", rootResourceType, absoluteUrlOfResource, domain, userName); string triggerWOPIViewUrl = this.GenerateRequestWOPIViewUrl(absoluteUrlOfResource, rootResourceType); string htmlReponseOfViewFile = this.TriggerRequestViewByUrl(triggerWOPIViewUrl, userName, password, domain); // Get the token string token = this.GetTokenByResponseOfRequestView(htmlReponseOfViewFile); token = HttpUtility.UrlEncode(token); // Get the WOPISrc value string wopiSrc = this.GetWOPISrcValueByResponseOfRequestViewFile(htmlReponseOfViewFile); // Construct the absolute request URL. wopiResourceUrl = this.GetAbsoluteRequestUrlWithToken(wopiSrc, token); // Verify the WOPI root resource URL. if (string.IsNullOrEmpty(wopiResourceUrl)) { string errorMsg = string.Format("Could not get the WOPI resource URL for a [{0}] type resource[{1}]", rootResourceType, absoluteUrlOfResource); throw new InvalidOperationException(errorMsg); } Uri wopiUrl; if (!Uri.TryCreate(wopiResourceUrl, UriKind.Absolute, out wopiUrl)) { string errorMsg = string.Format("The WOPI resource URL [{0}] is not valid absolute URL.", wopiResourceUrl); throw new InvalidOperationException(errorMsg); } string currentTransportValue = TokenAndRequestUrlHelper.CurrentHttpTransport.ToString(); if (!currentTransportValue.Equals(wopiUrl.Scheme, StringComparison.OrdinalIgnoreCase)) { wopiResourceUrl = string.Format( @"{0}://{1}{2}{3}", currentTransportValue, wopiUrl.Host, wopiUrl.LocalPath, wopiUrl.Query); } WOPIResourceUrlCache.AddWOPIResourceUrl(userName, domain, absoluteUrlOfResource, wopiResourceUrl); } return wopiResourceUrl; }
/// <summary> /// A method is used to generate request URL for viewing a normal resource in WOPI mode. /// </summary> /// <param name="absoluteUrlOfResource">A parameter represents the absolute URL of a normal resource.</param> /// <param name="rootResourceType">A parameter indicating the WOPI root resource URL type.</param> /// <returns>A return value represents the request URL for viewing a normal resource in WOPI mode. </returns> protected virtual string GenerateRequestWOPIViewUrl(string absoluteUrlOfResource, WOPIRootResourceUrlType rootResourceType) { if (string.IsNullOrEmpty(absoluteUrlOfResource)) { throw new ArgumentNullException("absoluteUrlOfResource"); } string placeHolderInPattern = string.Empty; string patternValue = string.Empty; switch (rootResourceType) { case WOPIRootResourceUrlType.FileLevel: { placeHolderInPattern = @"[filepath]"; patternValue = this.PatternOfRequestWOPIViewFile; break; } case WOPIRootResourceUrlType.FolderLevel: { placeHolderInPattern = @"[folderpath]"; patternValue = this.PatternOfRequestWOPIViewFolder; break; } default: { throw new InvalidOperationException("The test suite only supports folder and file two WOPI root resource URL formats."); } } // Verify whether the expected placeHolder exists in pattern. if (patternValue.IndexOf(placeHolderInPattern, StringComparison.OrdinalIgnoreCase) < 0) { string errorMsg = string.Format( "Could not find the [{0}] place holder, this place holder indicating the file path to view. Default format is [TargetSiteCollectionUrl]_layouts/15/WopiFrame.aspx?sourcedoc={0}", placeHolderInPattern); throw new InvalidOperationException(errorMsg); } // Ensure the http transport in "absoluteUrlOfResource" parameter should match the current transport used by this test suite. Uri targetResourceNormalPath; if (!Uri.TryCreate(absoluteUrlOfResource, UriKind.Absolute, out targetResourceNormalPath)) { string errorMsg = string.Format( "The target resource URL should be a valid absolute URL. Current[{0}]", absoluteUrlOfResource); throw new InvalidOperationException(errorMsg); } absoluteUrlOfResource = absoluteUrlOfResource.ToLower(CultureInfo.CurrentCulture); if (!targetResourceNormalPath.Scheme.Equals(this.currentTransport.ToString(), StringComparison.OrdinalIgnoreCase)) { string needReplaceTransportvalue = this.currentTransport.Equals(TransportProtocol.HTTP) ? "https" : "http"; needReplaceTransportvalue = string.Format(@"{0}://", needReplaceTransportvalue); string newReplaceValue = string.Format(@"{0}://", this.currentTransport); absoluteUrlOfResource = absoluteUrlOfResource.Replace(needReplaceTransportvalue, newReplaceValue); } patternValue = patternValue.ToLower(CultureInfo.CurrentCulture).Replace(placeHolderInPattern, "{0}"); absoluteUrlOfResource = HttpUtility.UrlEncode(absoluteUrlOfResource); string requestWopiViewUrlValue = string.Format(patternValue, absoluteUrlOfResource); return requestWopiViewUrlValue; }
/// <summary> /// A method is used to generate request URL for viewing a normal resource in WOPI mode. /// </summary> /// <param name="absoluteUrlOfResource">A parameter represents the absolute URL of a normal resource.</param> /// <param name="rootResourceType">A parameter indicating the WOPI root resource URL type.</param> /// <returns>A return value represents the request URL for viewing a normal resource in WOPI mode. </returns> protected virtual string GenerateRequestWOPIViewUrl(string absoluteUrlOfResource, WOPIRootResourceUrlType rootResourceType) { if (string.IsNullOrEmpty(absoluteUrlOfResource)) { throw new ArgumentNullException("absoluteUrlOfResource"); } string placeHolderInPattern = string.Empty; string patternValue = string.Empty; switch (rootResourceType) { case WOPIRootResourceUrlType.FileLevel: { placeHolderInPattern = @"[filepath]"; patternValue = this.PatternOfRequestWOPIViewFile; break; } case WOPIRootResourceUrlType.FolderLevel: { placeHolderInPattern = @"[folderpath]"; patternValue = this.PatternOfRequestWOPIViewFolder; break; } default: { throw new InvalidOperationException("The test suite only supports folder and file two WOPI root resource URL formats."); } } // Verify whether the expected placeHolder exists in pattern. if (patternValue.IndexOf(placeHolderInPattern, StringComparison.OrdinalIgnoreCase) < 0) { string errorMsg = string.Format( "Could not find the [{0}] place holder, this place holder indicating the file path to view. Default format is [TargetSiteCollectionUrl]_layouts/15/WopiFrame.aspx?sourcedoc={0}", placeHolderInPattern); throw new InvalidOperationException(errorMsg); } // Ensure the http transport in "absoluteUrlOfResource" parameter should match the current transport used by this test suite. Uri targetResourceNormalPath; if (!Uri.TryCreate(absoluteUrlOfResource, UriKind.Absolute, out targetResourceNormalPath)) { string errorMsg = string.Format( "The target resource URL should be a valid absolute URL. Current[{0}]", absoluteUrlOfResource); throw new InvalidOperationException(errorMsg); } absoluteUrlOfResource = absoluteUrlOfResource.ToLower(CultureInfo.CurrentCulture); if (!targetResourceNormalPath.Scheme.Equals(this.currentTransport.ToString(), StringComparison.OrdinalIgnoreCase)) { string needReplaceTransportvalue = this.currentTransport.Equals(TransportProtocol.HTTP) ? "https" : "http"; needReplaceTransportvalue = string.Format(@"{0}://", needReplaceTransportvalue); string newReplaceValue = string.Format(@"{0}://", this.currentTransport); absoluteUrlOfResource = absoluteUrlOfResource.Replace(needReplaceTransportvalue, newReplaceValue); } patternValue = patternValue.ToLower(CultureInfo.CurrentCulture).Replace(placeHolderInPattern, "{0}"); absoluteUrlOfResource = HttpUtility.UrlEncode(absoluteUrlOfResource); string requestWopiViewUrlValue = string.Format(patternValue, absoluteUrlOfResource); return(requestWopiViewUrlValue); }
/// <summary> /// A method used to get the WOPI resource URL by specified user credentials. /// </summary> /// <param name="absoluteUrlOfResource">A parameter represents the absolute URL of normal resource which will be used to get a WOPI resource URL.</param> /// <param name="rootResourceType">A parameter indicating the WOPI root resource URL type will be return.</param> /// <param name="userName">A parameter represents the name of user whose associated token will be return in the WOPI resource URL.</param> /// <param name="password">A parameter represents the password of the user.</param> /// <param name="domain">A parameter represents the domain of the user.</param> /// <returns>A return value represents the WOPI resource URL, which can be used in MS-WOPI operations.</returns> public string GetWOPIRootResourceUrl(string absoluteUrlOfResource, WOPIRootResourceUrlType rootResourceType, string userName, string password, string domain) { #region Verify the parameter if (string.IsNullOrEmpty(absoluteUrlOfResource)) { throw new ArgumentNullException("absoluteUrlOfResource"); } if (string.IsNullOrEmpty(userName)) { throw new ArgumentNullException("userName"); } if (string.IsNullOrEmpty(password)) { throw new ArgumentNullException("password"); } if (string.IsNullOrEmpty(domain)) { throw new ArgumentNullException("domain"); } if (WOPIRootResourceUrlType.FileLevel != rootResourceType && WOPIRootResourceUrlType.FolderLevel != rootResourceType) { throw new NotSupportedException(string.Format(@"The test suite only supports [{0}] and [{1}] two WOPI root resource URL formats.", WOPIRootResourceUrlType.FileLevel, WOPIRootResourceUrlType.FolderLevel)); } #endregion string wopiResourceUrl = string.Empty; if (!WOPIResourceUrlCache.TryGetWOPIResourceUrl(userName, domain, absoluteUrlOfResource, out wopiResourceUrl)) { // Get the response by specified user credential this.Site.Log.Add( LogEntryKind.Debug, "Try to get the [{0}] type WOPI URL for resource:[{1}]\r\n User:[{2}]\\[{3}]", rootResourceType, absoluteUrlOfResource, domain, userName); string triggerWOPIViewUrl = this.GenerateRequestWOPIViewUrl(absoluteUrlOfResource, rootResourceType); System.Threading.Thread.Sleep(10000); string htmlReponseOfViewFile = this.TriggerRequestViewByUrl(triggerWOPIViewUrl, userName, password, domain); // Get the token string token = this.GetTokenByResponseOfRequestView(htmlReponseOfViewFile); token = HttpUtility.UrlEncode(token); // Get the WOPISrc value string wopiSrc = this.GetWOPISrcValueByResponseOfRequestViewFile(htmlReponseOfViewFile); // Construct the absolute request URL. wopiResourceUrl = this.GetAbsoluteRequestUrlWithToken(wopiSrc, token); // Verify the WOPI root resource URL. if (string.IsNullOrEmpty(wopiResourceUrl)) { string errorMsg = string.Format("Could not get the WOPI resource URL for a [{0}] type resource[{1}]", rootResourceType, absoluteUrlOfResource); throw new InvalidOperationException(errorMsg); } Uri wopiUrl; if (!Uri.TryCreate(wopiResourceUrl, UriKind.Absolute, out wopiUrl)) { string errorMsg = string.Format("The WOPI resource URL [{0}] is not valid absolute URL.", wopiResourceUrl); throw new InvalidOperationException(errorMsg); } string currentTransportValue = TokenAndRequestUrlHelper.CurrentHttpTransport.ToString(); if (!currentTransportValue.Equals(wopiUrl.Scheme, StringComparison.OrdinalIgnoreCase)) { wopiResourceUrl = string.Format( @"{0}://{1}{2}{3}", currentTransportValue, wopiUrl.Host, wopiUrl.LocalPath, wopiUrl.Query); } WOPIResourceUrlCache.AddWOPIResourceUrl(userName, domain, absoluteUrlOfResource, wopiResourceUrl); } return(wopiResourceUrl); }
/// <summary> /// A method is used to get folder children's level URL. /// </summary> /// <param name="wopiRootResourceUrl">A parameter represents the WOPI resource URL for the folder level.</param> /// <param name="subResourceUrlType">A parameter represents the WOPI sub resource URL for the folder level.</param> /// <returns>A return value represents the folder children's level URL.</returns> public static string GetSubResourceUrl(string wopiRootResourceUrl, WOPISubResourceUrlType subResourceUrlType) { #region Verify parameter if (string.IsNullOrEmpty(wopiRootResourceUrl)) { throw new ArgumentNullException("wopiRootResourceUrl"); } Uri currentUri = null; if (!Uri.TryCreate(wopiRootResourceUrl, UriKind.Absolute, out currentUri)) { throw new ArgumentException("It must be a valid absolute URL", "wopiRootResourceUrl"); } string expectedIncludeStringValue = string.Empty; string expectedPatternValue = string.Empty; string expectedSubResourceUrlPostfix = string.Empty; WOPIRootResourceUrlType expectedRootResourceUrlType = WOPIRootResourceUrlType.FileLevel; switch (subResourceUrlType) { case WOPISubResourceUrlType.FolderChildrenLevel: { expectedIncludeStringValue = @"/folders/"; expectedPatternValue = folderLevelPattern; expectedSubResourceUrlPostfix = @"/children"; expectedRootResourceUrlType = WOPIRootResourceUrlType.FolderLevel; break; } case WOPISubResourceUrlType.FileContentsLevel: { expectedIncludeStringValue = @"/files/"; expectedPatternValue = fileLevelPattern; expectedSubResourceUrlPostfix = @"/contents"; expectedRootResourceUrlType = WOPIRootResourceUrlType.FileLevel; break; } default: { throw new InvalidOperationException(string.Format(@"The test suite only supports [{0}] and [{1}] two WOPI sub resource URL formats.", WOPISubResourceUrlType.FileContentsLevel, WOPISubResourceUrlType.FolderChildrenLevel)); } } if (wopiRootResourceUrl.IndexOf(expectedIncludeStringValue, StringComparison.OrdinalIgnoreCase) < 0) { string errorMsg = string.Format( @"To getting the [{0}] sub resource URL, the WOPI root resource URL must be [{1}] type, and its format must be [{2}] format.", subResourceUrlType, expectedRootResourceUrlType, expectedPatternValue); HelperBase.AppendLogs(typeof(TokenAndRequestUrlHelper), errorMsg); throw new InvalidOperationException(errorMsg); } string pathValueOfUrl = currentUri.AbsolutePath; if (pathValueOfUrl.EndsWith(@"/contents", StringComparison.OrdinalIgnoreCase) || pathValueOfUrl.EndsWith(@"/children", StringComparison.OrdinalIgnoreCase)) { string errorMsg = string.Format( @"The URL value has been WOPI sub resource URL:[{0}]", wopiRootResourceUrl); HelperBase.AppendLogs(typeof(TokenAndRequestUrlHelper), errorMsg); throw new InvalidOperationException(errorMsg); } #endregion Dictionary <string, string> wopiSrcAndTokenValues = GetWOPISrcAndTokenValueFromWOPIResourceUrl(wopiRootResourceUrl); string wopiSrcValue = wopiSrcAndTokenValues["WOPISrc"]; string tokenValue = wopiSrcAndTokenValues["Token"]; // Construct the sub WOPI resource URL. string wopiSubResourceUrl = string.Format( @"{0}{1}{2}{3}", wopiSrcValue, expectedSubResourceUrlPostfix, @"?access_token=", tokenValue); return(wopiSubResourceUrl); }