/// <summary> /// Synchronize an app from the tenant app catalog with the teams app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <returns></returns> public async Task <bool> SyncToTeamsAsync(AppMetadata appMetadata) { if (appMetadata == null || appMetadata.Id == null) { throw new ArgumentException(nameof(appMetadata)); } await new SynchronizationContextRemover(); return(await SyncToTeamsImplementation(appMetadata.Id)); }
/// <summary> /// Upgrades an app in a site /// </summary> /// <param name="appMetadata">The app metadata object of the app to upgrade.</param> /// <returns></returns> public async Task <bool> UpgradeAsync(AppMetadata appMetadata) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } return(await UpgradeAsync(appMetadata.Id)); }
/// <summary> /// Removes an app from the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <returns></returns> public async Task <bool> RemoveAsync(AppMetadata appMetadata) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } return(await BaseRequest(appMetadata.Id, "Remove", true)); }
/// <summary> /// Removes an app from the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> public async Task <bool> RemoveAsync(AppMetadata appMetadata, AppCatalogScope scope = AppCatalogScope.Tenant) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } await new SynchronizationContextRemover(); return(await BaseRequest(appMetadata.Id, AppManagerAction.Remove, true, null, scope)); }
/// <summary> /// Retracts an app in the app catalog. Notice that this will not remove the app from the app catalog. /// </summary> /// <param name="appMetadata">The app metadata object of the app to retract.</param> /// <returns></returns> public async Task <bool> RetractAsync(AppMetadata appMetadata) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } await new SynchronizationContextRemover(); return(await BaseRequest(appMetadata.Id, "Retract", true)); }
/// <summary> /// Uninstalls an app from a site. /// </summary> /// <param name="appMetadata">The app metadata object of the app to uninstall.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> public async Task <bool> UninstallAsync(AppMetadata appMetadata, AppCatalogScope scope = AppCatalogScope.Tenant) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } await new SynchronizationContextRemover(); return(await UninstallAsync(appMetadata.Id, scope)); }
/// <summary> /// Upgrades an app in a site /// </summary> /// <param name="appMetadata">The app metadata object of the app to upgrade.</param> /// <returns></returns> public async Task <bool> UpgradeAsync(AppMetadata appMetadata) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } await new SynchronizationContextRemover(); return(await UpgradeAsync(appMetadata.Id)); }
private static async Task <AppMetadata> GetAppMetaData(AppCatalogScope scope, ClientContext context, string accessToken, PnPHttpProvider httpClient, string requestDigest, string id) { AppMetadata returnValue = null; int retryCount = 0; int waitTime = 10; // seconds var metadataRequestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/AvailableApps/GetById('{id}')"; HttpRequestMessage metadataRequest = new HttpRequestMessage(HttpMethod.Get, metadataRequestUrl); metadataRequest.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { metadataRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } metadataRequest.Headers.Add("X-RequestDigest", requestDigest); while (returnValue == null && retryCount < 5) { // Perform actual post operation HttpResponseMessage metadataResponse = await httpClient.SendAsync(metadataRequest, new System.Threading.CancellationToken()); if (metadataResponse.IsSuccessStatusCode) { // If value empty, URL is taken var metadataResponseString = await metadataResponse.Content.ReadAsStringAsync(); if (metadataResponseString != null) { var metadataResponseJson = JObject.Parse(metadataResponseString); var returnedAddins = metadataResponseJson["d"]; returnValue = JsonConvert.DeserializeObject <AppMetadata>(returnedAddins.ToString()); } } else if (metadataResponse.StatusCode != HttpStatusCode.NotFound) { // Something went wrong... throw new Exception(await metadataResponse.Content.ReadAsStringAsync()); } if (returnValue == null) { // try again retryCount++; Thread.Sleep(waitTime * 1000); // wait 10 seconds } } return(returnValue); }
/// <summary> /// Deploys/trusts an app in the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to deploy.</param> /// <param name="skipFeatureDeployment">If set to true will skip the feature deployed for tenant scoped apps.</param> /// <returns></returns> public async Task <bool> DeployAsync(AppMetadata appMetadata, bool skipFeatureDeployment = true) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } var postObj = new Dictionary <string, object> { { "skipFeatureDeployment", skipFeatureDeployment } }; return(await BaseRequest(appMetadata.Id, "Deploy", true, postObj)); }
/// <summary> /// Deploys/trusts an app in the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to deploy.</param> /// <param name="skipFeatureDeployment">If set to true will skip the feature deployed for tenant scoped apps.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> public async Task <bool> DeployAsync(AppMetadata appMetadata, bool skipFeatureDeployment = true, AppCatalogScope scope = AppCatalogScope.Tenant) { if (appMetadata == null) { throw new ArgumentException(nameof(appMetadata)); } if (appMetadata.Id == Guid.Empty) { throw new ArgumentException(nameof(appMetadata.Id)); } var postObj = new Dictionary <string, object> { { "skipFeatureDeployment", skipFeatureDeployment } }; await new SynchronizationContextRemover(); return(await BaseRequest(appMetadata.Id, AppManagerAction.Deploy, true, postObj, scope)); }
private async Task <AppMetadata> BaseAddRequest(byte[] file, string filename, bool overwrite = false, bool appCatalog = true) { AppMetadata returnValue = null; var context = _context; if (appCatalog == true) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); } var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/Add(overwrite={(overwrite.ToString().ToLower())}, url='{filename}')"; var requestDigest = await context.GetRequestDigest(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } request.Headers.Add("X-RequestDigest", requestDigest); request.Headers.Add("binaryStringRequestBody", "true"); request.Content = new ByteArrayContent(file); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { var responseJson = JObject.Parse(responseString); var id = responseJson["d"]["UniqueId"].ToString(); var metadataRequestUrl = $"{context.Web.Url}/_api/web/tenantappcatalog/AvailableApps/GetById('{id}')"; HttpRequestMessage metadataRequest = new HttpRequestMessage(HttpMethod.Post, metadataRequestUrl); metadataRequest.Headers.Add("accept", "application/json;odata=verbose"); if (!string.IsNullOrEmpty(accessToken)) { metadataRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } metadataRequest.Headers.Add("X-RequestDigest", requestDigest); // Perform actual post operation HttpResponseMessage metadataResponse = await httpClient.SendAsync(metadataRequest, new System.Threading.CancellationToken()); if (metadataResponse.IsSuccessStatusCode) { // If value empty, URL is taken var metadataResponseString = await metadataResponse.Content.ReadAsStringAsync(); if (metadataResponseString != null) { var metadataResponseJson = JObject.Parse(metadataResponseString); var returnedAddins = metadataResponseJson["d"]; returnValue = JsonConvert.DeserializeObject <AppMetadata>(returnedAddins.ToString()); } } else { // Something went wrong... throw new Exception(await metadataResponse.Content.ReadAsStringAsync()); } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => returnValue)); }
/// <summary> /// Deploys/trusts an app in the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to deploy.</param> /// <param name="skipFeatureDeployment">If set to true will skip the feature deployed for tenant scoped apps.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> public bool Deploy(AppMetadata appMetadata, bool skipFeatureDeployment = true, AppCatalogScope scope = AppCatalogScope.Tenant) { return(Task.Run(() => DeployAsync(appMetadata, skipFeatureDeployment, scope)).GetAwaiter().GetResult()); }
/// <summary> /// Removes an app from the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <returns></returns> public bool Remove(AppMetadata appMetadata) { return(RemoveAsync(appMetadata).GetAwaiter().GetResult()); }
/// <summary> /// Retracts an app in the app catalog. Notice that this will not remove the app from the app catalog. /// </summary> /// <param name="appMetadata">The app metadata object of the app to retract.</param> /// <returns></returns> public bool Retract(AppMetadata appMetadata) { return(RetractAsync(appMetadata).GetAwaiter().GetResult()); }
/// <summary> /// Deploys/trusts an app in the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to deploy.</param> /// <param name="skipFeatureDeployment">If set to true will skip the feature deployed for tenant scoped apps.</param> /// <returns></returns> public bool Deploy(AppMetadata appMetadata, bool skipFeatureDeployment = true) { return(DeployAsync(appMetadata, skipFeatureDeployment).GetAwaiter().GetResult()); }
/// <summary> /// Upgrades an app in a site /// </summary> /// <param name="appMetadata">The app metadata object of the app to upgrade.</param> /// <returns></returns> public bool Upgrade(AppMetadata appMetadata) { return(UpgradeAsync(appMetadata).GetAwaiter().GetResult()); }
/// <summary> /// Removes an app from the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <returns></returns> public bool Remove(AppMetadata appMetadata) { return(Task.Run(() => RemoveAsync(appMetadata)).GetAwaiter().GetResult()); }
/// <summary> /// Uninstalls an app from a site. /// </summary> /// <param name="appMetadata">The app metadata object of the app to uninstall.</param> /// <returns></returns> public bool Uninstall(AppMetadata appMetadata) { return(UninstallAsync(appMetadata).GetAwaiter().GetResult()); }
/// <summary> /// Removes an app from the app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <param name="scope">Specifies the app catalog to work with. Defaults to Tenant</param> /// <returns></returns> public bool Remove(AppMetadata appMetadata, AppCatalogScope scope = AppCatalogScope.Tenant) { return(Task.Run(() => RemoveAsync(appMetadata, scope)).GetAwaiter().GetResult()); }
private async Task <AppMetadata> BaseAddRequest(byte[] file, string filename, bool overwrite, int timeoutSeconds, AppCatalogScope scope) { AppMetadata returnValue = null; var context = _context; if (scope == AppCatalogScope.Tenant) { // switch context to appcatalog var appcatalogUri = _context.Web.GetAppCatalog(); context = context.Clone(appcatalogUri); } var accessToken = context.GetAccessToken(); using (var handler = new HttpClientHandler()) { context.Web.EnsureProperty(w => w.Url); // we're not in app-only or user + app context, so let's fall back to cookie based auth if (String.IsNullOrEmpty(accessToken)) { handler.SetAuthenticationCookies(context); } using (var httpClient = new PnPHttpProvider(handler)) { string requestUrl = $"{context.Web.Url}/_api/web/{(scope == AppCatalogScope.Tenant ? "tenant" : "sitecollection")}appcatalog/Add(overwrite={(overwrite.ToString().ToLower())}, url='{filename}')"; var requestDigest = await context.GetRequestDigestAsync(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUrl); request.Headers.Add("accept", "application/json;odata=nometadata"); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); } else { if (context.Credentials is NetworkCredential networkCredential) { handler.Credentials = networkCredential; } } request.Headers.Add("X-RequestDigest", requestDigest); request.Headers.Add("binaryStringRequestBody", "true"); request.Content = new ByteArrayContent(file); httpClient.Timeout = new TimeSpan(0, 0, timeoutSeconds); // Perform actual post operation HttpResponseMessage response = await httpClient.SendAsync(request, new System.Threading.CancellationToken()); if (response.IsSuccessStatusCode) { // If value empty, URL is taken var responseString = await response.Content.ReadAsStringAsync(); if (responseString != null) { using (var jsonDocument = JsonDocument.Parse(responseString)) { if (jsonDocument.RootElement.TryGetProperty("UniqueId", out JsonElement uniqueIdElement)) { var id = uniqueIdElement.GetString(); returnValue = await GetAppMetaData(scope, context, accessToken, httpClient, requestDigest, id); } } } } else { // Something went wrong... throw new Exception(await response.Content.ReadAsStringAsync()); } } } return(await Task.Run(() => returnValue)); }
/// <summary> /// Upgrades an app in a site /// </summary> /// <param name="appMetadata">The app metadata object of the app to upgrade.</param> /// <returns></returns> public bool Upgrade(AppMetadata appMetadata) { return(Task.Run(() => UpgradeAsync(appMetadata)).GetAwaiter().GetResult()); }
/// <summary> /// Uninstalls an app from a site. /// </summary> /// <param name="appMetadata">The app metadata object of the app to uninstall.</param> /// <returns></returns> public bool Uninstall(AppMetadata appMetadata) { return(Task.Run(() => UninstallAsync(appMetadata)).GetAwaiter().GetResult()); }
/// <summary> /// Synchronize an app from the tenant app catalog with the teams app catalog /// </summary> /// <param name="appMetadata">The app metadata object of the app to remove.</param> /// <returns></returns> public bool SyncToTeams(AppMetadata appMetadata) { return(Task.Run(() => SyncToTeamsAsync(appMetadata)).GetAwaiter().GetResult()); }