Working with Github private repository using bash on Windows 10

There are times, we want to collaborate with other stakeholders in Github in a private manner. Meaning, we need to work and collaborate on a private Github repository. If you have a private Github private repository ready for collaboration, the most proven way to work with that is to leverage one of the following two options.

  1. Leverage SSH keys at the Github account level. So that you can work with Github private repository using SSH keys. The whole idea is that you will be generating an RSA key pair using SSH Key gen utility, add the private key portion of the key pair to the SSH agent and upload the public key portion of the key pair to the Github account settings. The advantage of this approach is that you have one SSH key defined at the Github account level to manage or work with all the private Github repositories created under that account.githubsshkey
  2. Leverage Deploy Keys at the individual repository level. I have learnt that a Deploy Key can be associated with only one Github repository at this point in time. githubdeploykey

The advantage of the second approach is that you can have a dedicated  key or set of deploy keys for individual repositories.

In this post, i’ll be covering the option #1. Basically i will leverage bash on windows 10 to work with private github repository using SSH keys. My windows 10 is already set up with Ubuntu 18.0.4 for Windows sub-system for linux.  I’m not covering the steps for setting up bash on Windows 10 using Windows subsystem for linux. You can refer microsoft documenation for that. Let’s move to the SSH set up process for Github.

Navigate to the directory in windows 10, where you want to generate SSH key pair.

pic1

Type ‘bash’ on the command prompt. It will launch the bash shell on windows 10. Basically the Windows folder that you have pointed will be mounted to the ubuntu 18.0.4 bash shell.

Now you can generate the SSH key pair using ‘ssh-keygen’ utility.

ssh-keygen -t rsa -b 4096 -C “your_email@example.com

Enter the name of the file for saving the key pair and provide any arbitrary passphrase when prompted.

pic2

Start the ssh on the bash shell. We need to explicty start it, because the run levels of this is different from a standard ubuntu desktop OS. I have learnt that the SSH agent does not get started automatically when you invoke bash on windows 10, unlike a standard ubuntu desktop OS.

eval $(ssh-agent -s)

pic3

Add the private key portion of the generated key pair to the SSH agent.

ssh-add keyname

If you getting a permission error for the generated key pair, the key will not get added successfully to the agent.

pic4

Even if you try to modify the permission of the key using ‘chmod 400’ or ‘chmod 600’ on the mounted directory, it won’t be successful. Becuase i’ve learnt that changing file permissions using chmod on the mounted directory (from windows 10) does not work.

The best way to fix this is to copy the key to a folder under the ubuntu user root directory, not to any windows mounted directory on bash.

Check if the directory ~/.ssh already exists on the bash shell. If not, explicitly create a directory ~/.ssh and exit the bash shell.

Again, navigate to the directory in windows 10 where the key pairs are generated and launch bash from there.

copy private key to ~/.ssh

pic5.JPG

Navigate to ~/.ssh and change permissions using any one of the following commands.

chmod 400 sundargitsshkey

chmod 600 sundargitsshkey

pic6

Copy the public key of the generated key pair (with ‘.pub’ suffix) to New –> SSH Key under Github account settings. Basically copy the content of the public key using any of the text editors and paste there in textbox available in New –> SSH Key under Github account settings.

Navigate to the SSH config file located in ‘/etc/ssh/ssh_config’ and add an entry for ‘IdentityFile ~/.ssh/sundargitsshkey’

sudo nano ssh_config

pic7

Start the SSH agent explicitly.

eval $(ssh-agent -s)

Verify the connectivity to Github using this command ‘SSH -T git@github.com’. You need to user the Github user name as ‘git’. If you try to use your actual Github user name, you’ll get errors.

It will ask you to confirm to accept the warning on authenticity of github.com. Accept it and provide passphrase for private key file when prompted. You’ll get the confirmation for successful authentication to make SSH calls into Github account from your bash shell.

pic8

Now you do git clone, commit and push to any number of repositories under your Github account using SSH, be it a private repository or public repository. This completes the post on working with Github private repository using bash on Windows 10.

 

Enable static website hosting in S3

AWS Simple Storage Service (S3) offers one of the powerful capability to host static websites. In this post let’s cover the steps for the same.

Create a sample bucket by name ‘mytestdomain.com’. The convention is that bucket name should match with the website domain name.

In this case the domain name for the static website is mytestdomain.com. The S3 bucket should match that name.

image

Enable public read access to this bucket.

image

Enable static web site hosting for the bucket by selecting ‘Use this bucket to host a static website’ and specifying the index document and error document.


image

Upload the index.html and error.html file and grant the public read access to it. Now access the static website url

provided by S3. It should be in this format.

http://s3bucketname.s3-website-region.amazonaws.com/

It should render the index.html in the browser

image

To render this website with the actual domain name, we need to leverage Route 53 DNS service offered by AWS.

Create a hosted zone for our custom domain.

image

Once the hosted zone is created, S3 presents with list of name servers. It should be mapped with the domain registrar for routing the request through Route 53.

The next step is to create a Record Set for the Hosted Zone bye selecting the Alias Target to the S3 bucket enabled for static website hosting.

image

It takes few minutes for the record set changes to get propagated. After that try accessing the website domain url. It should render the index page. This completes this article.





How to get list items in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can fetch the list items of a SharePoint list in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘GetListItemsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint.com/_api/web/lists/GetByTitle(‘Shared%20Assets’)/items.

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered.

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given full-control permission for site-collection. Otherwise, it will not be able to fetch the fields collection.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web/list" Right="Read" />
  </AppPermissionRequests>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/GetByTitle('Site%20Assets')/items?@target='" + HostWebUrl

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Open the App.js and paste the following code

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d.results;
    var resultcount = results.length;
    var finalresult;

    var i;
    var tempobject;


    for (i = 0; i < resultcount - 1; i++)
    {
        tempobject = results[i];
        finalresult = finalresult+ "Item title is" + tempobject["Title"] + "Item id is " + tempobject["Id"];
        
    }
   
    document.getElementById("message").innerText = finalresult;
  

   
    
   
    
}



function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/GetByTitle('Site%20Assets')/items?@target='" + HostWebUrl + "'",
        method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            
        },
        success: successHandler,
        error: errorHandler
    });

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Run the above piece of code and you will be see the below result.

image

 Subscribe to my blog

How to get a SharePoint group in SharePoint 2013 Online using REST

In this post, we’ll see how to get a SharePoint Group in SharePoint Online using REST. I’ll be using a SharePoint hosted app for the purpose of demonstration.

Launch Visual Studio 2013.

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/sitegroups(index)

index – an integer that refers a group uniquely in the site.

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given the following permission.

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />
  </AppPermissionRequests>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’.

var executor = new SP.RequestExecutor(AppWebUrl);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/sitegroups(index)?@target='" + HostWebUrl + "'",

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

e)Copy and paste the following code in the App.js (replace Ii t the existing code over there)

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d;
    document.getElementById("message").innerText = "Field title is" + results["Title"] + "Field Id is" + results["Id"];

}

function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/sitegroups(3)?@target='" + HostWebUrl + "'",
        method: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
        },
        success: successHandler,
        error: errorHandler
    });

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Run the above piece of code, now you will be able to get the title and id for the site collection group (no: 3).

image

 Subscribe to my blog

 

How to get SharePoint fields collection in SharePoint 2013 Online using REST

In this post, we’ll see how we can fetch the fields collection of a SharePoint web in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘GetFieldsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/fields

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given full-control permission for site-collection. Otherwise, it will not be able to fetch the fields collection.

 <AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
  </AppPermissionRequests>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/fields?@target='" + HostWebUrl + "'",

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Open the App.js and paste the following code

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});


function successHandler(data) {

    var jsonObj = JSON.parse(data.body);
    var results = jsonObj.d;
    document.getElementById("message").innerText = "Field title is" + results["Title"] + "Field Id is" + results["Id"];

}

function errorHandler(data, errorCode, errorMessage) {


    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);

    executor.executeAsync({
        url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/fields?@target='" + HostWebUrl + "'",
        method: "POST",
        body: "{ '__metadata': { 'type': 'SP.Field' }, 'Title': 'Comments', 'FieldTypeKind': 3 }",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
        },
        success: successHandler,
        error: errorHandler
    });

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

image

This completes this demo.

 Subscribe to my blog

How to get SharePoint 2013 web property using REST in SharePoint Online

In this post, we’ll see how we can access the property of a SharePoint web in SharePoint 2013 online using REST. For the purpose of demonstration, I’ll be using a SharePoint hosted app.

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and and name it as ‘GetWebdetailsREST’

I will be accessing the following REST endpoint for getting a web title

https://yoursite.sharepoint/_api/web/title

Since the call is initiating from AppWeb to HostWeb, it will present a classical cross-domain scenario, where I will be using the SP 2013 javascript cross-domain libraries to manage this call.

After creating the App project in Visual Studio 2013, the following points need to be considered

a)The App Permission need to be left with default setting of Internal.

<AppPrincipal>
    <Internal/>
  </AppPrincipal>
  

With this setting, the SharePoint hosted app will have access to the Host Web by default.

b)The App need to be given read permission for site-collection

<AppPermissionRequests>
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="Read" />
  </AppPermissionRequests>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

c)The executor object need to be instantiated with the parameter of ‘AppWebUrl’, not the ‘HostWebUrl.  (you’ll see more detailed code in the coming sections). If you instantiate it with ‘HostWebUrl, you will get an error like ‘App web not found’

var executor = new SP.RequestExecutor(AppWebUrl);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

d)To access the HostWeb rest end points the url property in the cross-domain call need to be set in this fashion.

AppWebUrl + "/_api/SP.AppContextSite(@target)/web/title?@target='" + HostWebUrl + "'",

Open the App.js and paste the following code

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;


// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
    //getUserName();

    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);

});

// This function prepares, loads, and then executes a SharePoint query to get the current users information
function getUserName() {
   
}



function successHandler(data)
{
    
    var jsonObj = JSON.parse(data.body);
    document.getElementById("message").innerText = "Web title from REST call is"+ jsonObj.d["Title"];

}

function errorHandler(data, errorCode, errorMessage) {
   

    document.getElementById("message").innerText = "failure";

}

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}

function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);
    executor.executeAsync(
        {
            url: AppWebUrl + "/_api/SP.AppContextSite(@target)/web/title?@target='" + HostWebUrl + "'",
            type: "GET",
            crossDomain:true,

            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/json;odata=verbose",
                "content-length": 1028,
                "X-RequestDigest": $("#__REQUESTDIGEST").val()

            },
            success: successHandler,
            error: errorHandler
        }
        );

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

image

Now you can see the updated site title in the App. This completes this demo.

 Subscribe to my blog

How to setup multi-factor authentication in Office 365

In this post, we’ll see how we can enable multi-factor authentication for Office 365. The concept of multi-factor authentication has be become increasingly popular nowadays for bringing the additional layer of security hardening. Multi-factor authentication is a form of authentication, which enforces more than one form of authentication to verify the legitimacy of the transactions performed by a user. Nowadays, the most common form of second-form of authentication in to validate the Authorization code by sending it to the user’s mobile devices.

Let’s see the steps to enable multi-factor authentication in Office 365.

Log in to Office 365 admin portal, go to Users –> Active Users.

image

Click setup and you will be presented with the following screen.

image

Click ‘Enable’ link on the bottom right and the following screen will pop-up.

 

image

Click ‘enable multi-factor auth’.

Now you will get a confirmation that multi-factor authentication is enabled for selected accounts.

When I log in next time, it asks for me to setup the second form of authentication.

image

Click ‘Set it up now’.

image

It sends a 6 digit verification code to the registered mobile number. You are all set for multi-factor authentication enabled Office 365 tenant. This wraps up my quick how-to article.

At this point of time, the multi-factor authentication is available for Office 365 Midsize Business, Enterprise plans, Academic plans, Nonprofit plans, and standalone Office 365 plans, including Exchange Online and SharePoint Online. It is not available for Office 365 Small Business and Office 365 Dedicated plans as of now. The detailed Faqs about multi-factor authentication is available here. 

 Subscribe to my blog

Understanding App Only Permission policy in SharePoint 2013 App model

In this post, we’ll understand what is an App Only Permission policy in SharePoint 2013 App model with a sample app project. The SharePoint 2013 App permissions are of three types and they are as follows :-

  • App Only
  • User Only
  • App+User

When the logged in user does not have enough privileges to perform a certain action or set of actions, the App Only permission comes into picture. The App can elevate its permission using the App Only permission or context. A SharePoint 2013 App configured with App Only permission or context can only installed by the site-collection administrator at this point of time.

I’ll be using a Provider hosted app for the purpose of this demonstration. I have a user called ‘User A’ who does not have permission to modify the Title of SharePoint lists in the site-collection. I will be using App Only context to elevate the App’s permission and change the List Title.

I have a list called ‘Announcements’ and I will be changing its Title using App Only permission or context.

image

Launch Visual Studio 2013.

File –> New –> Office/SharePoint –> Apps and name it as ‘AppOnlyContextApp’

Select the app hosting type as Provider hosted apps.

In order to update the Title of the SharePoint List (at the root of the site-collection), provide the Full Control to Site-Collection.

image

Set App Only permission in the AppManifest.XML file

<?xml version="1.0" encoding="utf-8" ?>
<!--Created:cb85b80c-f585-40ff-8bfc-12ff4d0e34a9-->
<App xmlns="http://schemas.microsoft.com/sharepoint/2012/app/manifest"
     Name="AppOnlyContext"
     ProductID="{b5e637d0-8a34-498c-b8cf-c40b3d0e9ef3}"
     Version="1.0.0.0"
     SharePointMinVersion="15.0.0.0"
>
  <Properties>
    <Title>AppOnlyContext</Title>
    <StartPage>~remoteAppUrl/Pages/Default.aspx?{StandardTokens}</StartPage>
  </Properties>

  <AppPrincipal>
    <RemoteWebApplication ClientId="*" />
  </AppPrincipal>
  <AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection" Right="FullControl" />
  </AppPermissionRequests>
</App>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Copy and paste the following code for the default.aspx.cs file and I have added the necessary logic in the page_load method to update Title of a particular list.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AppOnlyContextWeb
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_PreInit(object sender, EventArgs e)
        {
            Uri redirectUrl;
            switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
            {
                case RedirectionStatus.Ok:
                    return;
                case RedirectionStatus.ShouldRedirect:
                    Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                    break;
                case RedirectionStatus.CanNotRedirect:
                    Response.Write("An error occurred while processing your request.");
                    Response.End();
                    break;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            // The following code gets the client context and Title property by using TokenHelper.
            // To access other properties, the app may need to request permissions on the host web.
            var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            using (var clientContext = spContext.CreateUserClientContextForSPHost())
            {
         
                //Load the sharepoint web
                clientContext.Load(clientContext.Web, web => web.Title);
                clientContext.ExecuteQuery();
                Response.Write(clientContext.Web.Title);

                //Load the list-collection in the sharepoint web
                clientContext.Load(clientContext.Web.Lists);                
                clientContext.ExecuteQuery();

                //Change the title of announcment list to some arbitrary title
                clientContext.Web.Lists[1].Title = "SundarAnnouncements";
                clientContext.Web.Lists[1].Update();
                clientContext.ExecuteQuery();


            }
        }
    }
}

Hit F5 and run the App in Visual Studio. Now we can verify the elevation of App permission by using App Only policy, by validating the change in List title.

image

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 Subscribe to my blog

How to get list of Fields in a SharePoint List in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can get the list of Fields in a SharePoint List in SharePoint 2013 Online using CSOM. I’ll be using a Console application for the purpose of demonstration.

Open Visual Studio 2013.

File –> New Project –> Visual C# –> Console Application and name it as ‘GetFieldsCSOM’

Add a reference to the ‘Microsoft.SharePoint.Client’ and ‘Microsoft.SharePoint.Client.Runtime’ assemblies

Import the following namespaces

using Microsoft.SharePoint.Client;
using System.Security;

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The following code will invoke the GetbyTitle method of Lists class and access the Fields property collection.

namespace GetFieldsCSOM
{
    class Program
    {
        
        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

        static void Main(string[] args)
        {
            //Replace it with the url of your tenant or your site-collection
            string SiteUrl = "https://yoursite.sharepoint.com";
            System.Uri oUri = new System.Uri(SiteUrl);
            using (ClientContext oClientContext = new ClientContext(SiteUrl))
            {
                //Replace it with your user id for SharePoint Online
                string UserName = "userid@yoursite.onmicrosoft.com";
                //Replace it with your password
                string Password = "password";
                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);
                oClientContext.Load(oClientContext.Web.Lists.GetByTitle("TestList").Fields);
                oClientContext.ExecuteQuery();
                FieldCollection oFieldCollection = oClientContext.Web.Lists.GetByTitle("TestList").Fields;

                foreach(Field oField in oFieldCollection)
                {
                    Console.WriteLine(oField.Title);
                
                }
                Console.ReadLine();
            }
        }
    }
}

image
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 Subscribe to my blog