Example #1
0
        /// <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));
        }
Example #2
0
 /// <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));
 }
Example #3
0
 /// <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));
 }
Example #4
0
        /// <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));
        }
Example #5
0
        /// <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));
        }
Example #6
0
        /// <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));
        }
Example #7
0
        /// <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));
        }
Example #8
0
        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);
        }
Example #9
0
        /// <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));
        }
Example #10
0
        /// <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));
        }
Example #11
0
        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));
        }
Example #12
0
 /// <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());
 }
Example #13
0
 /// <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());
 }
Example #14
0
 /// <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());
 }
Example #15
0
 /// <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());
 }
Example #16
0
 /// <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());
 }
Example #17
0
 /// <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());
 }
Example #18
0
 /// <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());
 }
Example #19
0
 /// <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());
 }
Example #20
0
        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));
        }
Example #21
0
 /// <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());
 }
Example #22
0
 /// <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());
 }
Example #23
0
 /// <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());
 }