public async Task Docs_BasicConcepts_Expand_AllowedChildTypes()
        {
            // ACTION for doc
            dynamic content = await RESTCaller.GetContentAsync(new ODataRequest
            {
                Path   = "/Root/Content/IT",
                Expand = new[] { "AllowedChildTypes" }
            });

            //Console.WriteLine(content.AllowedChildTypes.Count);

            // ASSERT
            Assert.AreEqual(0, content.AllowedChildTypes.Count);

            // ACTION-2
            dynamic content2 = await RESTCaller.GetContentAsync(new ODataRequest
            {
                Path   = "/Root/Content",
                Expand = new[] { "AllowedChildTypes" }
            });

            // ASSERT-2
            Assert.AreEqual(10, content2.AllowedChildTypes.Count);
            Assert.AreEqual("Folder", content2.AllowedChildTypes[0].Name.ToString());
        }
        public async Task Docs_Collaboration_Versioning_TakeLockOver()
        {
            Assert.Inconclusive();
            //UNDONE:---- ERROR: The server returned an error (HttpStatus: InternalServerError): User not found by the parameter: 12345
            // ALIGN
            // ReSharper disable once InconsistentNaming
            await using var Console = new StringWriter();
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "File");

            try
            {
                // ACTION for doc
                var body   = @"models=[{""user"": ""12345""}]";
                var result = await RESTCaller.GetResponseStringAsync(
                    "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "TakeLockOver", HttpMethod.Post, body);

                Console.WriteLine(result);

                // ASSERT
                var message = Console.GetStringBuilder().ToString();
                Assert.Inconclusive();
            }
            finally
            {
                var c = await Content.LoadAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx");

                if (c != null)
                {
                    await c.DeleteAsync(true);
                }
            }
        }
        public async Task Docs_BasicConcepts_ChildrenInlineCount()
        {
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");

            //UNDONE:- Feature request: should returns a collection with property: TotalCount
            //var result3 = await Content.LoadCollectionAsync(new ODataRequest
            //{
            //    Path = "/Root/IMS/BuiltIn/Portal",
            //    Top = 3,
            //    Skip = 4,
            //    InlineCount = InlineCountOptions.AllPages // Default, AllPages, None
            //});

            // ACTION for doc
            var result = await RESTCaller.GetResponseJsonAsync(new ODataRequest
            {
                IsCollectionRequest = true,
                Path       = "/Root/Content/IT",
                Top        = 3,
                Skip       = 4,
                Parameters = { { "$inlinecount", "allpages" } }
            });

            // ASSERT
            // { "d": { "__count": 1, "results": [] }}

            var array       = ((JToken)result).SelectTokens("$.d.results.*").ToArray();
            var inlineCount = ((JToken)result).SelectToken("$.d.__count").Value <int>();

            Assert.AreNotEqual(0, inlineCount);
            Assert.AreNotEqual(array.Length, inlineCount);
        }
        public async Task Docs_BasicConcepts_Scenario()
        {
            //UNDONE:- Feature request: scenario filter of Actions
            //dynamic content8 = await Content.LoadAsync(new ODataRequest
            //{
            //    Path = "/Root/IMS",
            //    Expand = new[] { "Actions" },
            //    Select = new[] { "Name", "Actions" },
            //    Scenario = "UserMenu",
            //});

            // ACTION for doc
            dynamic content = await RESTCaller.GetContentAsync(new ODataRequest
            {
                Path       = "/Root/Content/IT",
                Expand     = new[] { "Actions" },
                Select     = new[] { "Actions" },
                Parameters = { { "scenario", "ContextMenu" } }
            });

            //foreach(var item in content.Actions)
            //    Console.WriteLine(item.Name);

            // ASSERT
            Assert.Inconclusive();
        }
        public async Task <AuthorityInfo> GetAuthorityInfoAsync(ServerContext server, CancellationToken cancel = default)
        {
            var req = new ODataRequest(server)
            {
                Path       = "/Root",
                ActionName = "GetClientRequestParameters"
            };

            // The client type is hardcoded because the real client id
            // is provided by the repository using the request below.
            req.Parameters.Add("clientType", "client");

            //TODO: remove this assertion when the GetResponse method below
            // is able to receive a cancellation token.
            cancel.ThrowIfCancellationRequested();

            try
            {
                dynamic response = await RESTCaller.GetResponseJsonAsync(req, server)
                                   .ConfigureAwait(false);

                return(new AuthorityInfo
                {
                    Authority = response.authority,
                    ClientId = response.client_id
                });
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, $"Could not access repository {server.Url} for getting the authority url.");
            }

            return(new AuthorityInfo());
        }
Beispiel #6
0
        public async Task Docs_ContentManagement_ListFields_Add()
        {
            // ALIGN
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");

            try
            {
                // ACTION for doc
                var body   = @"models=[{
                    ""__ContentType"": ""IntegerFieldSetting"",
                    ""Name"": ""MyField1"",
                    ""DisplayName"": ""My Field 1"",
                    ""Compulsory"": true,
                    ""MinValue"": 10}]";
                var result = await RESTCaller.GetResponseStringAsync(
                    "/Root/Content/IT/Document_Library", null, HttpMethod.Post, body);

                Console.WriteLine(result);

                // ASSERT
                Assert.Inconclusive();
            }
            finally
            {
                await Content.DeleteAsync("/Root/Content/IT/Document_Library", true, CancellationToken.None);
            }
        }
Beispiel #7
0
        static void Main(string[] args)
        {
            var tradeDataRequest = new TradeDataRequest();

            tradeDataRequest.ForEnterprise(1).ForClient(1).ForAccounts(new int[] { 1, 4 });
            Console.WriteLine(RESTCaller.GetDataAsync(tradeDataRequest).GetAwaiter().GetResult());
        }
        public async Task Docs_Collaboration_Versioning_RestoreOldVersion()
        {
            // ALIGN
            // ReSharper disable once InconsistentNaming
            await using var Console = new StringWriter();
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "File");

            try
            {
                // ACTION for doc
                var body   = @"models=[{""version"": ""V1.0.A""}]";
                var result = await RESTCaller.GetResponseStringAsync(
                    "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "RestoreVersion", HttpMethod.Post, body);

                Console.WriteLine(result);

                // ASSERT
                var message = Console.GetStringBuilder().ToString();
                Assert.Inconclusive();
            }
            finally
            {
                var c = await Content.LoadAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx");

                if (c != null)
                {
                    await c.DeleteAsync(true);
                }
            }
        }
Beispiel #9
0
        private static async Task <Stream> GetBinaryAsync()
        {
            var documentStream = new MemoryStream();

            try
            {
                // download the whole file from the server
                await RESTCaller.GetStreamResponseAsync(ContentId, Version, async response =>
                {
                    if (response == null)
                    {
                        throw new ClientException($"Content {ContentId} {Version} not found.",
                                                  HttpStatusCode.NotFound);
                    }

                    await response.Content.CopyToAsync(documentStream).ConfigureAwait(false);
                    documentStream.Seek(0, SeekOrigin.Begin);
                }, CancellationToken.None).ConfigureAwait(false);
            }
            catch (ClientException ex)
            {
                if (AsposeTools.ContentNotFound(ex))
                {
                    return(null);
                }

                Logger.WriteError(ContentId, 0, "Error during remote file access.", ex, StartIndex, Version);

                // We need to throw the error further to let the main catch block
                // log the error and set the preview status to 'Error'.
                throw;
            }

            return(documentStream);
        }
        public async Task Docs_Collaboration_Approval_Reject()
        {
            Assert.Inconclusive();
            //UNDONE:---- ERROR: The server returned an error (HttpStatus: InternalServerError): Currently this action is not allowed on this content.
            // ALIGN
            // ReSharper disable once InconsistentNaming
            await using var Console = new StringWriter();
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "File");

            try
            {
                // ACTION for doc
                var body   = @"models=[{""rejectReason"": ""Reject reason""}]";
                var result = await RESTCaller.GetResponseStringAsync(
                    "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "Reject", HttpMethod.Post, body);

                Console.WriteLine(result);

                // ASSERT
                var message = Console.GetStringBuilder().ToString();
                Assert.Inconclusive();
            }
            finally
            {
                var c = await Content.LoadAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx");

                if (c != null)
                {
                    await c.DeleteAsync(true);
                }
            }
        }
        public async Task Docs_Collaboration_Versioning_CheckOut()
        {
            // ALIGN
            // ReSharper disable once InconsistentNaming
            await using var Console = new StringWriter();
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "File");

            try
            {
                // ACTION for doc
                var result = await RESTCaller.GetResponseJsonAsync(method : HttpMethod.Post, requestData : new ODataRequest
                {
                    IsCollectionRequest = false,
                    Path       = "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx",
                    ActionName = "Checkout",
                });

                Console.WriteLine(result);

                // ASSERT
                var message = Console.GetStringBuilder().ToString();
                Assert.Inconclusive();
            }
            finally
            {
                var c = await Content.LoadAsync("/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx");

                if (c != null)
                {
                    await c.DeleteAsync(true);
                }
            }
        }
        // GetContentAsync GetResponseStringAsync GetResponseJsonAsync
        public async Task Docs_BasicConcepts_Select()
        {
            // ACTION for doc
            dynamic content = await RESTCaller.GetContentAsync(new ODataRequest
            {
                Path   = "/Root/Content/IT",
                Select = new[] { "DisplayName", "Description" }
            });

            // ASSERT-1
            var responseString = await RESTCaller.GetResponseStringAsync(new ODataRequest
            {
                Path   = "/Root/Content/IT",
                Select = new[] { "DisplayName", "Description" }
            });

            Assert.AreEqual("{\"d\":{\"DisplayName\":\"IT\",\"Description\":null}}", responseString.RemoveWhitespaces());

            // ASSERT-2
            var responseJson = await RESTCaller.GetResponseJsonAsync(new ODataRequest
            {
                Path   = "/Root/Content/IT",
                Select = new[] { "DisplayName", "Description" }
            });

            var displayName = responseJson.d.DisplayName.ToString();
            var description = responseJson.d.Description.ToString();

            Assert.AreEqual(displayName, content.DisplayName.ToString());
            Assert.AreEqual(description, content.Description.ToString());
        }
Beispiel #13
0
        /// <summary>
        /// Checks whether a user has the provided permissions on the provided content.
        /// </summary>
        /// <param name="contentId">Id of a content.</param>
        /// <param name="permissions">Permission names to check.</param>
        /// <param name="user">The user who's permissions need to be checked. If it is not provided, the server checks the current user.</param>
        /// <param name="server">Target server.</param>
        public static async Task <bool> HasPermissionAsync(int contentId, string[] permissions, string user = null, ServerContext server = null)
        {
            if (permissions == null || permissions.Length == 0)
            {
                throw new InvalidOperationException("Please provide at least one permission entry.");
            }

            var requestData = new ODataRequest()
            {
                SiteUrl    = ServerContext.GetUrl(server),
                ContentId  = contentId,
                ActionName = "HasPermission"
            };

            requestData.Parameters.Add("permissions", string.Join(",", permissions));

            if (!string.IsNullOrEmpty(user))
            {
                requestData.Parameters.Add("user", user);
            }

            var result = await RESTCaller.GetResponseStringAsync(requestData.GetUri(), server);

            bool hasPermission;

            if (bool.TryParse(result, out hasPermission))
            {
                return(hasPermission);
            }

            return(false);
        }
        /// <summary>
        /// Checks whether a user has the provided permissions on the provided content.
        /// </summary>
        /// <param name="contentId">Id of a content.</param>
        /// <param name="permissions">Permission names to check.</param>
        /// <param name="user">The user who's permissions need to be checked. If it is not provided, the server checks the current user.</param>
        /// <param name="server">Target server.</param>
        public static async Task <bool> HasPermissionAsync(int contentId, string[] permissions, string user = null, ServerContext server = null)
        {
            if (permissions == null || permissions.Length == 0)
            {
                throw new InvalidOperationException("Please provide at least one permission entry.");
            }

            var requestData = new ODataRequest(server)
            {
                ContentId   = contentId,
                ActionName  = "HasPermission",
                Permissions = permissions,
                User        = user
            };

            var result = await RESTCaller.GetResponseStringAsync(requestData.GetUri(), server).ConfigureAwait(false);

            bool hasPermission;

            if (bool.TryParse(result, out hasPermission))
            {
                return(hasPermission);
            }

            return(false);
        }
Beispiel #15
0
        public async Task Docs_ContentManagement_Move_Single()
        {
            // ALIGN
            await EnsureContentAsync("/Root/Content/IT/Document_Library", "DocumentLibrary");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Munich", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Chicago", "Folder");
            await EnsureContentAsync("/Root/Content/IT/Document_Library/Chicago/100Pages.pdf", "File");

            try
            {
                // ACTION for doc
                var body   = @"models=[{""targetPath"": ""/Root/Content/IT/Document_Library/Munich"",
                ""paths"": [""/Root/Content/IT/Document_Library/Chicago/100Pages.pdf""]}]";
                var result = await RESTCaller.GetResponseStringAsync(
                    "/Root", "MoveBatch", HttpMethod.Post, body);

                Console.WriteLine(result);

                // ASSERT
                Assert.Inconclusive();
            }
            finally
            {
                var c = await Content.LoadAsync("/Root/Content/IT/Document_Library/Munich");

                if (c != null)
                {
                    await c.DeleteAsync(true);
                }
            }
        }
Beispiel #16
0
        public async Task Upload_ByPath()
        {
            var uploadRootPath = "/Root/UploadTests";
            var uploadFolder   = await Content.LoadAsync(uploadRootPath).ConfigureAwait(false);

            if (uploadFolder == null)
            {
                uploadFolder = Content.CreateNew("/Root", "SystemFolder", "UploadTests");
                await uploadFolder.SaveAsync().ConfigureAwait(false);
            }

            var fileName = Guid.NewGuid() + ".txt";

            using (var uploadStream = Tools.GenerateStreamFromString(_fileContent))
                // ACTION
                await Content.UploadAsync(uploadRootPath, fileName, uploadStream, "File").ConfigureAwait(false);

            // ASSERT
            var filePath = RepositoryPath.Combine(uploadRootPath, fileName);
            var content  = await Content.LoadAsync(filePath).ConfigureAwait(false);

            string downloadedFileContent = null;
            await RESTCaller.GetStreamResponseAsync(content.Id, async response =>
            {
                if (response == null)
                {
                    return;
                }
                using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var reader = new StreamReader(stream))
                        downloadedFileContent = reader.ReadToEnd();
            }, CancellationToken.None);

            Assert.AreEqual(_fileContent, downloadedFileContent);
        }
Beispiel #17
0
        public async Task Test_Different_Restful_Calls()
        {
            // Creating REST caller
            var caller = new RESTCaller();

            // Making GET call to https://jsonplaceholder.typicode.com/posts?userId=1
            var getResponse = await caller.GetAsync(
                uri : new Uri("https://jsonplaceholder.typicode.com/posts"),
                parameters : new Dictionary <string, string>
            {
                { "userId", "1" }
            });

            Assert.AreEqual(HttpStatusCode.OK, getResponse.HttpStatusCode);
            Assert.AreEqual("application/json; charset=utf-8", getResponse.ContentType);
            Assert.IsFalse(string.IsNullOrWhiteSpace(getResponse.Text));

            // Making POST call to https://jsonplaceholder.typicode.com/posts
            var postResponse = await caller.PostAsync(
                uri : new Uri("https://jsonplaceholder.typicode.com/posts"),
                body : @"{ ""title"": ""foo"", ""body"": ""bar"", ""userId"": 1 }");

            Assert.AreEqual(HttpStatusCode.OK, getResponse.HttpStatusCode);
            Assert.AreEqual("application/json; charset=utf-8", getResponse.ContentType);
            Assert.IsFalse(string.IsNullOrWhiteSpace(getResponse.Text));
        }
        public async Task Docs_BasicConcepts_GetCtd()
        {
            /*
             * // WARNING This code cannot run if the #1064 does not exist.
             * // ACTION for doc
             * string ctd = null;
             * await RESTCaller.GetStreamResponseAsync(1064, async message =>
             * {
             *  ctd = await message.Content.ReadAsStringAsync();
             * }, CancellationToken.None);
             */

            // IMPROVED TEST
            var content = await Content.LoadAsync("/Root/System/Schema/ContentTypes/GenericContent/File").ConfigureAwait(false);

            var fileId = content.Id;

            // ACTION
            string ctd = null;
            await RESTCaller.GetStreamResponseAsync(fileId, async message =>
            {
                ctd = await message.Content.ReadAsStringAsync().ConfigureAwait(false);
            }, CancellationToken.None).ConfigureAwait(false);

            // ASSERT
            Assert.IsTrue(ctd.StartsWith("<?xml") || ctd.StartsWith("<ContentType"));
            Assert.IsTrue(ctd.Trim().EndsWith("</ContentType>"));
        }
Beispiel #19
0
 /// <summary>
 /// Removes permission break on the provided content.
 /// </summary>
 /// <param name="contentId">Id of a content.</param>
 /// <param name="server">Target server.</param>
 public static async Task UnbreakInheritanceAsync(int contentId, ServerContext server = null)
 {
     await RESTCaller.GetResponseStringAsync(contentId, SETPERMISSIONS, HttpMethod.Post, JsonHelper.Serialize(new
     {
         inheritance = "unbreak"
     }),
                                             server);
 }
        public async Task Docs_BasicConcepts_GetSchema()
        {
            // ACTION for doc
            string schema = await RESTCaller.GetResponseStringAsync("/Root", "GetSchema");

            // ASSERT
            Assert.Inconclusive();
        }
Beispiel #21
0
        // ============================================================================== Static methods

        private static async Task <SyncConfiguration> LoadConfiguration()
        {
            try
            {
                dynamic settingsContent = Content.LoadAsync(SettingsPath).Result;
                if (settingsContent == null)
                {
                    return(null);
                }

                string binaryUrl = _siteUrl.TrimEnd('/') + settingsContent.Binary.__mediaresource.media_src +
                                   "&includepasswords=true";

                var settingsText = await RESTCaller.GetResponseStringAsync(new Uri(binaryUrl));

                var config = JsonHelper.Deserialize <SyncConfiguration>(settingsText);

                // decrypt passwords and inject them back to the configuration
                foreach (var server in config.Servers.Where(server => server.LogonCredentials != null && !string.IsNullOrEmpty(server.LogonCredentials.Password)))
                {
                    var request = new ODataRequest
                    {
                        ActionName          = "Decrypt",
                        Path                = "Root",
                        IsCollectionRequest = false,
                        SiteUrl             = _siteUrl
                    };

                    try
                    {
                        server.LogonCredentials.Password = await RESTCaller.GetResponseStringAsync(
                            request.GetUri(),
                            ClientContext.Current.Servers[0],
                            HttpMethod.Post,
                            JsonHelper.Serialize(new { text = server.LogonCredentials.Password }));
                    }
                    catch (ClientException cex)
                    {
                        AdLog.LogError("Error during password decryption. " + Common.FormatClientException(cex));
                    }
                    catch (Exception ex)
                    {
                        AdLog.LogException(ex);
                    }
                }

                // preload all AD-related content types from the server
                ADRelatedContentTypes = await LoadADRelatedContentTypes();

                return(config);
            }
            catch (Exception ex)
            {
                AdLog.LogException(ex);
            }

            return(null);
        }
        public async Task ParseException()
        {
            var webex = new WebException("error");
            var ce    = await RESTCaller.GetClientExceptionAsync(webex, "url", HttpMethod.Post, "body");

            Assert.AreEqual("url", ce.Data["Url"]);
            Assert.AreEqual("POST", ce.Data["Method"]);
            Assert.AreEqual("body", ce.Data["Body"]);
        }
        public async Task Docs_Permissions_Main_GetPermissions_CurrentUser()
        {
            //UNDONE:- Feature request: Content.GetPermissionAsync
            // ACTION for doc
            var result = await RESTCaller.GetResponseStringAsync("/Root/Content/IT", "GetPermissions");

            // ASSERT
            Assert.Inconclusive();
        }
        public async Task Docs_BasicConcepts_GetSingleProperty()
        {
            var response =
                // ACTION for doc
                //UNDONE:- Feature request: Content.GetPropertyAsync: await Content.GetPropertyAsync("/Root/IMS", "DisplayName");
                await RESTCaller.GetResponseStringAsync("/Root/Content/IT", "DisplayName");

            // ASSERT
            Assert.AreEqual("{\"d\":{\"DisplayName\":\"IT\"}}", response.RemoveWhitespaces());
        }
        public async Task Docs_BasicConcepts_GlobalMetadata()
        {
            var url = ClientContext.Current.Server.Url;

            var response =
                // ACTION for doc
                await RESTCaller.GetResponseStringAsync(
                    new Uri(url + "/OData.svc/$metadata"));

            // ASSERT
            Assert.Inconclusive();
        }
        public async Task Docs_BasicConcepts_GetSinglePropertyValue()
        {
            var url = ClientContext.Current.Server.Url;

            var response =
                // ACTION for doc
                //UNDONE:- Feature request: Content.GetPropertyValueAsync: await Content.GetPropertyValueAsync("/Root/IMS", "DisplayName");
                await RESTCaller.GetResponseStringAsync(new Uri(url + "/OData.svc/Root/Content/('IT')/DisplayName/$value"));

            // ASSERT
            Assert.AreEqual("IT", response.RemoveWhitespaces());
        }
Beispiel #27
0
        public async Task Docs_Preview_Main_RegeneratePreviews()
        {
            Assert.Inconclusive();
            //UNDONE: this test has not run yet
            // ACTION for doc
            await RESTCaller.GetResponseStringAsync(
                "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "RegeneratePreviews",
                HttpMethod.Post);

            // ASSERT
            Assert.Inconclusive();
        }
Beispiel #28
0
        public async Task Docs_Preview_Main_GetPageCount()
        {
            Assert.Inconclusive();
            //UNDONE: this test has not run yet
            // ACTION for doc
            var result = await RESTCaller.GetResponseStringAsync(
                "/Root/Content/IT/Document_Library/Calgary/BusinessPlan.docx", "GetPageCount", HttpMethod.Post);

            //Console.WriteLine(result);

            // ASSERT
            Assert.Inconclusive();
        }
Beispiel #29
0
        public async Task Docs_Sharing_Main_GetSharing()
        {
            Assert.Inconclusive();
            //UNDONE: this test has not run yet
            // ACTION for doc
            var result = await RESTCaller.GetResponseStringAsync(
                "/Root/Content/IT", "GetSharing");

            //Console.WriteLine(result);

            // ASSERT
            Assert.Inconclusive();
        }
Beispiel #30
0
        /// <summary>
        /// Sets the provided permissions on the provided content.
        /// </summary>
        /// <param name="contentId">Id of a content.</param>
        /// <param name="permissions">Permission settings to be sent to the server.</param>
        /// <param name="server">Target server.</param>
        public static async Task SetPermissionsAsync(int contentId, SetPermissionRequest[] permissions, ServerContext server = null)
        {
            if (permissions == null || permissions.Length == 0)
            {
                throw new InvalidOperationException("Please provide at least one permission entry.");
            }

            await RESTCaller.GetResponseStringAsync(contentId, SETPERMISSIONS, HttpMethod.Post, JsonHelper.Serialize(new
            {
                r = permissions
            }),
                                                    server);
        }