Tuesday, September 17, 2019

List of HTTP status codes

List of HTTP status codes

All HTTP response status codes are separated into five classes (or categories). The first digit of the status code defines the class of response. The last two digits do not have any class or categorization role. There are five values for the first digit:
  • 1xx (Informational): The request was received, continuing process
  • 2xx (Successful): The request was successfully received, understood and accepted
  • 3xx (Redirection): Further action needs to be taken in order to complete the request
  • 4xx (Client Error): The request contains bad syntax or cannot be fulfilled
  • 5xx (Server Error): The server failed to fulfill an apparently valid request



HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:
  1. Informational responses (100199),
  2. Successful responses (200299),
  3. Redirects (300399),
  4. Client errors (400499),
  5. and Server errors (500599).





Reference Links:

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes


https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

https://www.restapitutorial.com/httpstatuscodes.html

Friday, September 6, 2019

SPO Site Script & Site design + SharePoint Online

Site design is a collection of actions that SharePoint runs when creating a new site. Actions describe changes to apply to the new site, such as creating a new list or applying a theme. The actions are specified in a JSON script, which is a list of all actions to apply. When a script runs, SharePoint completes each action in the order listed.

Each action is specified by the "verb" value in the JSON script. Also, actions can have subactions that are also "verb" values. 

The overall JSON structure is specified as follows:

{ "$schema": "schema.json", "actions": [ ... <one or more verb actions> ... ], "bindata": { }, "version": 1 };


Get started creating site designs and site scripts


Scoping access to site designs


Site design JSON schema



SharePoint site design: PowerShell cmdlets



Site design and site script REST API



/*create site columns */
{
    "verb": "createSiteColumn",
    "fieldType": "Text",
    "internalName": "GhostBloggerName",
    "displayName": "GhostBloggerName",
    "isRequired": false
},

{
    "verb": "createSiteColumn",
    "fieldType": "Boolean",
    "internalName": "IsGhostBlogger",
    "displayName": "IsGhostBlogger",
    "isRequired": false
},


/*Add Content type*/ { "verb": "createContentType", "name": "GIP_Inv_Post_CT", "id": "0x0100A4790B87CB420C48A9D102196F7269DF", "description": "", "parentId": "0x01", "hidden": false, "subactions": [ { "verb": "addSiteColumn", "internalName": "GhostBloggerName", "addToDefaultView": true }, { "verb": "addSiteColumn", "internalName": "IsGhostBlogger", "addToDefaultView": true } ]
},


addContentType & removeContentType
 {
          "verb": "addContentType",
          "name": "Project Document"
        },
        {
          "verb": "removeContentType",
          "name": "Document"
        }


/* Create Page - Content.aspx*/ { "verb": "createPage", "fileName": "Content.aspx", "pageData": { "Title": "Content", "BannerImageUrl": "", "CanvasContent1": "<div>/div>", "LayoutWebpartsContent": "" }, "setAsHomePage": false },
https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-design-json-schema



/*Set a site logo*/

{ "verb": "setSiteLogo", "url": "/Customer Event Collateral/logo.jpg" }


/*Install an add-in or solution */

To get the solution ID, sign in to a site by using the Connect-PnPOnline cmdlet, and then run Get-PnPApp.
{ "verb": "installSolution", "id": "d40e4edc-a6da-4cd8-b82d-bba970976803" }

/**Register an extension**/
Use the associateExtension action to register a deployed SharePoint Framework extension from the tenant app catalog.

{ "verb": "associateExtension", "title": "SPFXApplicationCustomizer Example", "location": "ClientSideExtension.ApplicationCustomizer", "clientSideComponentId": "40d64749-a6e5-4691-b440-1e32fb6sean5", "scope": "Web" }

/**Activate a Feature**/

Site scoped features cannot be activated through Site Designs at this time.

{ "verb": "activateSPFeature", "featureId": "00bfea71-ec85-4903-972d-ebe475780106" }

/**Trigger a flow**/

{"verb": "triggerFlow", "url": "<A trigger URL of the Flow.>", "name": "Record and tweet site creation event", "parameters": { "event": "Microsoft Event", "product": "SharePoint" } }


/**Configure regional settings**/
{ "verb": "setRegionalSettings", "timeZone": 2, /* Greenwich Mean Time */ "locale": 1050, /* Croatia */ "sortOrder": 6, /* Croatian */ "hourFormat": "24" }

/**POWERSHELL COMMANDS**/


$adminSiteUrl = "https://TENANT-admin.sharepoint.com"
$siteScriptFile = "C:\GK\DemoSiteScript.json"
$webTemplate = "68"
$OrgName="TENANT"
$siteScriptTitle = "Custom Com Site Script"
$siteDesignTitle = "Custom Com Site Design"
$siteDesignDescription = "Custom Com site design"
$previewImageUrl = ""
$designPackageId = "00000000-0000-0000-0000-000000000000"

$cred = Get-Credential
Connect-SPOService $adminSiteUrl -Credential $cred

Add-SPOSiteScript 
$siteScript = (Get-Content $siteScriptFile -Raw | Add-SPOSiteScript -Title $siteScriptTitle) | Select -First 1 Id

Add-SPOSiteDesign
Add-SPOSiteDesign -SiteScripts $siteScript.Id -Title $siteDesignTitle -WebTemplate $webTemplate -Description $siteDesignDescription -PreviewImageUrl $previewImageUrl -DesignPackageId $designPackageId

Id                  : 4bdf454c-1395-4d6d-9d9d-01c546786a74
Title               : Custom Com Site Design
WebTemplate         : 68
SiteScriptIds       : {6bb738e1-4abc-4a93-8c97-fae8e6815e30}
Description         : Custom Com site design with create page
PreviewImageUrl     :
PreviewImageAltText :
IsDefault           : False
Version             : 1
DesignPackageId     : 00000000-0000-0000-0000-000000000000

MODIFYING AN EXISTING SITE SCRIPT
$siteScriptFile = "E:\SiteScripts\KRDemoSiteScript.json"
Get-SPOSiteScript
$siteScriptId ="bbbdc8a9-270d-4c89-80a7-1725ba07dea3"
Set-SPOSiteScript -Identity $siteScriptId -Content (Get-Content $siteScriptFile -Raw)


DELETING YOUR SITE DESIGNS AND SITE SCRIPTS
$siteScriptId=""
#$siteScriptId=""

Remove-SPOSiteDesign -Identity $siteDesignId
Remove-SPOSiteScript -Identity $siteScriptId

Remove-SPOSiteDesign -Identity "2ed26bec-ea03-4d4d-8343-ea8e7a8d78b0"
Remove-SPOSiteScript -Identity "4c9d6ff8-1088-40ff-8350-1eea62158900"


#Get the content of the JSON file and add it to the site script.
$siteScriptListContent = Get-Content 'SiteScripts\site-script-lists.json' -Raw
$siteScriptList = Add-SPOSiteScript -Title "CnC Lists" -Description "Adds a custom document library to the site" -Content $siteScriptListContent

#Get the content of the JSON file and add it to the site script.
$siteScriptTriggerFlowContent = Get-Content 'SiteScripts\site-script-triggerFlow.json' -Raw
$siteScriptTriggerFlow = Add-SPOSiteScript -Title "CnC Trigger Flow" -Description "Triggers a Microsoft Flow" -Content $siteScriptTriggerFlowContent

#Create a basic site design only using the lists site script.
Add-SPOSiteDesign -Title "CnC Basic Communication site" -WebTemplate "68" -SiteScripts $siteScriptList.ID -Description "CnC basic communication site"

#Create an advanced site design by using the lists as well as flow site scripts
Add-SPOSiteDesign -Title "CnC Advanced Communication site" -WebTemplate "68" -SiteScripts $siteScriptList.ID, $siteScriptTriggerFlow.ID -Description "CnC advanced communication site"



Connect-PnPOnline $adminSiteUrl -Credential $cred
OR
Connect-PnPOnline -Url "https://TENANT-admin.sharepoint.com"

Connect-PnPOnline -Url $adminSiteUrl
Get-PnPApp
Id                                   Title                                         Deployed AppCatalogVersion Installed
                                                                                                              Version
--                                   -----                                         -------- ----------------- ---------
3b47da46-8ff4-46bc-bb19-e2c90d3e3832 helloworld-webpart-react-client-side-solution True     1.0.0.0
5e8c223e-440c-4cb7-ab00-a6ca6d3fd5b3 Improved Content editor                       True     1.0.0.0
42dbd79a-96d9-4012-b898-738e0f356004 SPFx Fantastic 40 WebParts                    True     1.0.4.0
b7e2b572-1bc7-4053-9545-d8fd0129abc3 Modern Script Editor web part by Puzzlepart   True     1.0.0.10
fd26d165-7216-442b-a138-4b8e7825d083 singlepageapppart-client-side-solution        True     1.0.0.0
1ceea556-f363-4cab-8597-2f7494d0c8c2 footer-app-customizer-client-side-solution    True     1.0.0.0
f9608df3-2244-40fb-8ef9-7dc28f4e994e header-style-client-side-solution             True     1.3.0.0
3e9f5c2d-67c6-48f3-a8fe-5ca6466f410b default-sp-webpart-client-side-solution       True     1.0.0.0


/****/

Reference Links:

https://docs.microsoft.com/en-us/sharepoint/dev/declarative-customization/site-design-json-schema

https://laurakokkarinen.com/the-ultimate-guide-to-sharepoint-site-designs-and-site-scripts/

https://www.vrdmn.com/2018/01/combine-and-re-use-multiple-site.html


PROVISIONING TEAMS WITH A SITE DESIGN, FLOW AND MICROSOFT GRAPH



DOES IT SPARK JOY? POWERSHELL SCRIPTS FOR KEEPING YOUR DEVELOPMENT ENVIRONMENT TIDY AND SPOTLESS




MY MOST USED POWERSHELL SCRIPTS FOR MANAGING SHAREPOINT ONLINE





AUTHENTICATING TO OFFICE 365 APIS WITH A CERTIFICATE — STEP-BY-STEP

https://laurakokkarinen.com/authenticating-to-office-365-apis-with-a-certificate-step-by-step/




HOW TO BUILD A GUEST USER SELF-SERVICE REGISTRATION FOR OFFICE 365 WITH AZURE

https://laurakokkarinen.com/how-to-build-a-guest-user-self-service-registration-for-office-365-with-azure/



HOW TO COMPLETELY DISABLE EXTERNAL SHARING FOR A SINGLE OFFICE 365 GROUP


https://laurakokkarinen.com/how-to-completely-disable-external-sharing-for-a-single-office-365-group/



Wednesday, August 14, 2019

Regex.IsMatch & Regex.Matches- get the Matched words - Matches

Regex.IsMatch   - it will return true or false.

&  Regex.Matches -  get the Matched words - Matches


var filterWords = GetTermsFromSPlist(log, secureUsrPwd);
                    try
                    {
                        string profanePattern = "";
                        bool isFirst = true;
                        filterWords.ToList().ForEach(i =>
                        {
                            if (isFirst)
                            {
                                profanePattern = "\\b" + i + "\\b";
                                isFirst = false;
                            }
                            else
                                profanePattern += "|\\b" + i + "\\b";
                        });
                        //Write Regex method
                        IsBlockedProfanity = Regex.IsMatch(htmltotext, profanePattern, RegexOptions.IgnoreCase);




                       
                        if (IsBlockedProfanity)
                        {
                            var matches = Regex.Matches(htmltotext, profanePattern, RegexOptions.IgnoreCase);
                            string flaggedTermsString1 = string.Empty;
                            if (matches.Count > 0)
                            {
                                foreach (var bWord in matches)
                                {
                                    flaggedTermsString1 += $"{bWord},";
                                }
                            }
}

Tuesday, August 13, 2019

Read site page contents in Sharepoint using CSOM

In Site Pages library (list type of ListTemplateType.WebPageLibrary) the content for list item depending on the underling the content type could be extracted from:

  • WikiField field in case of Wiki Page
  • CanvasContent1 field in case of Site Page (aka "modern" page)

Example
var listTitle = "Site Pages";
var list = ctx.Web.Lists.GetByTitle(listTitle);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, icol => icol.Include( i => i["WikiField"], i => i["CanvasContent1"], i => i["FileRef"], i => i.ContentType));
ctx.ExecuteQuery();
foreach (var item in items)
{
     Console.WriteLine(">>> {0}", item["FileRef"]);
     switch (item.ContentType.Name)
     {
        case "Site Page":
          Console.WriteLine(item["CanvasContent1"]);
          break;
        case "Wiki Page":
          Console.WriteLine(item["WikiField"]);
          break;

     }    
 }



#region ReadModernPageData
            void ReadingModernPageData()
            {
                bool IsAzureProfanity = false;
                bool IsBlockedProfanity = false;
                using (var postPageCtx = new ClientContext(pageSiteUrl))
                {
                    SecureString secureUsrPwd = new SecureString();
                    foreach (char p in password)
                    {
                        secureUsrPwd.AppendChar(p);
                    }
                    secureUsrPwd.MakeReadOnly();
                    string postBody = string.Empty;
                    TextModerationResults1 demoModeration = new TextModerationResults1();
                    IList<string> returnOutPut = new List<string>();
                    List<string> finalOutPut = new List<string>();
                    byte[] postBodyByteArray;
                    postPageCtx.Credentials = new SharePointOnlineCredentials(userName, secureUsrPwd);
                    var list = postPageCtx.Web.Lists.GetByTitle(pageLibName);
                    var item = list.GetItemById(pageItemID);
                    postPageCtx.Load(item);
                    postPageCtx.ExecuteQuery();
                    var fieldVals = item.FieldValues;

                    var htmltotext = HtmlToNormalizedPlainText(fieldVals["CanvasContent1"].ToString().ToLower());
                    var postPageUrl = pageSiteUrl + "/SitePages/" + fieldVals["FileLeafRef"].ToString();
                    string postTitle = fieldVals["Title"].ToString();
                    log.Info(postPageUrl);
                    //var Author = fieldVals["Author"];
                    FieldUserValue Author = (FieldUserValue)item["Author"];
                    var user = postPageCtx.Web.EnsureUser(Author.LookupValue);
                    // load the data with the context               
                    postPageCtx.Load(user);
                    postPageCtx.ExecuteQuery();
                    var createdBy = user.Email; //+ ";" + hubManagersEmail;

                    var filterWords = GetTermsFromSPlist(log, secureUsrPwd);
                    try
                    {
                        string profanePattern = "";
                        bool isFirst = true;
                        filterWords.ToList().ForEach(i =>
                        {
                            if (isFirst)
                            {
                                profanePattern = "\\b" + i + "\\b";
                                isFirst = false;
                            }
                            else
                                profanePattern += "|\\b" + i + "\\b";
                        });
                        //Write Regex method
                        IsBlockedProfanity = Regex.IsMatch(htmltotext, profanePattern, RegexOptions.IgnoreCase);
                        if (IsBlockedProfanity)
                        {
                            ClientContext invReportCtx = GetSiteContext(inv_SiteUrl, userName, secureUsrPwd);
                            //AddToReportedContent(invReportCtx, inv_ReportedContentLstNm, pageSiteUrl, postPageUrl, "Blocked Words Found", "ARContent", "inProgress");
                            //Send email via exchange server
                            // var isSentEmail = SendMail(userName, password, createdBy, postTitle, "Blocked Words Profanity Found & Terms are :", postPageUrl);
                            var isSentEmail=SendMailViaCtx(postPageCtx, userName, password, createdBy,hubManagersEmail, "Warning! | Blocked Words Found in post | " + postTitle, "Blocked Words Profanity Found & Terms are :", postPageUrl);
                           
                        }
                    }

                    catch (Exception)
                    {
                        log.Info("Error while checking profanity using RegEx");
                    }


                    if (htmltotext.Length <= 1024)
                    {
                        postBody = htmltotext;
                        postBodyByteArray = Encoding.UTF8.GetBytes(postBody);
                        postBodyMemoryStream = new MemoryStream(postBodyByteArray);
                        returnOutPut.Clear();
                        (demoModeration, returnOutPut, IsAzureProfanity) = TextContentModeration1.CheckContentForModeration(postBodyMemoryStream, log);
                        if (IsAzureProfanity)
                        {
                            IsAzureProfanityFinal = true;
                        }
                        finalOutPut.AddRange(returnOutPut.Distinct());
                    }
                    else
                    {
                        char[] delimiters = new char[] { ',', ';', '.' };
                        string[] splittedSentence = htmltotext.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                        string normalizedText1024Char = string.Empty;
                        int screenTextLength = 0;
                        int splittedSentenceIndexCounter = 0;
                        foreach (string sentence in splittedSentence)
                        {
                            splittedSentenceIndexCounter++;
                            screenTextLength = normalizedText1024Char.Length + sentence.Length;
                            if (screenTextLength <= 1024)
                            {
                                normalizedText1024Char += sentence;
                                if (splittedSentenceIndexCounter == splittedSentence.Length)
                                {
                                    postBody = normalizedText1024Char;
                                    postBodyByteArray = Encoding.UTF8.GetBytes(postBody);
                                    postBodyMemoryStream = new MemoryStream(postBodyByteArray);
                                    returnOutPut.Clear();
                                    (demoModeration, returnOutPut, IsAzureProfanity) = TextContentModeration1.CheckContentForModeration(postBodyMemoryStream, log);
                                    if (IsAzureProfanity)
                                    {
                                        IsAzureProfanityFinal = true;
                                    }
                                    finalOutPut.AddRange(returnOutPut.Distinct());
                                }
                            }
                            else
                            {
                                postBody = normalizedText1024Char;
                                postBodyByteArray = Encoding.UTF8.GetBytes(postBody);
                                postBodyMemoryStream = new MemoryStream(postBodyByteArray);
                                returnOutPut.Clear();
                                (demoModeration, returnOutPut, IsAzureProfanity) = TextContentModeration1.CheckContentForModeration(postBodyMemoryStream, log);
                                if (IsAzureProfanity)
                                {
                                    IsAzureProfanityFinal = true;
                                }
                                finalOutPut.AddRange(returnOutPut.Distinct());
                                screenTextLength = 0;
                                normalizedText1024Char = string.Empty;
                                screenTextLength = sentence.Length;
                                normalizedText1024Char = sentence;
                                // very few scenarios - last sentence will validate in below code
                                if (splittedSentenceIndexCounter == splittedSentence.Length)
                                {
                                    postBody = normalizedText1024Char;
                                    postBodyByteArray = Encoding.UTF8.GetBytes(postBody);
                                    postBodyMemoryStream = new MemoryStream(postBodyByteArray);
                                    returnOutPut.Clear();
                                    (demoModeration, returnOutPut, IsAzureProfanity) = TextContentModeration1.CheckContentForModeration(postBodyMemoryStream, log);
                                    if (IsAzureProfanity)
                                    {
                                        IsAzureProfanityFinal = true;
                                    }
                                    finalOutPut.AddRange(returnOutPut.Distinct());
                                }
                            }
                        }
                    }
                    // add to Inv_RequestContent list
                    string flaggedTermsString = string.Empty;

                    foreach (var distinctITem in finalOutPut.Distinct())
                    {
                        flaggedTermsString += $"{distinctITem},";
                    }

                    log.Info(finalOutPut.Distinct().Count().ToString());

                    if (finalOutPut.Distinct().Count() > 0)
                    {
                        //Update List Item:
                        ClientContext invReportCtx = GetSiteContext(inv_SiteUrl, userName, secureUsrPwd);
                        AddToReportedContent(invReportCtx, inv_ReportedContentLstNm, pageSiteUrl, postPageUrl, "Azure Profanity & Terms are :" + flaggedTermsString, "ARContent", "inProgress");

                        //Send email via exchange server
                        var isSentEmail = SendMailViaCtx(postPageCtx, userName, password, createdBy,hubManagersEmail, "Profanity Alert! Azure Profanity found in Post ! "+postTitle, "Azure Profanity & Terms are :" + flaggedTermsString, postPageUrl);

                    }
                    else
                    {
                        log.Info("Page doesn't have data");
                    }

                }
                #endregion

is Required & Validation message in an adaptive card

The parameter to make the text field mandatory in adaptive card is "isRequired", pls try modify the required parameter with the be...