Friday, September 25, 2015

SharePoint 2013 App Only Policy

Hi,

Here you can find a useful info about SharePoint 2013 App Only Policy and diagram

As developers start working with SharePoint 2013 apps, you quickly realize how permissions with apps work when performing work on behalf of a user.  I can log in as the site collection administrator, and execute an app that writes to a list and see the action fail because permission was denied.  The reason it was denied is because the app did not request write permissions to the list it was trying to write to.  Similarly, I can log in as a user who only has read permission to a list and invoke an app that has full control permission and see an attempt to write to a list fail because permission was denied.  The reason this time is that even though the app had permissions, the user did not.
This is explained in the following diagram.  The app is making a call into SharePoint, and it does so by providing the OAuth access token.  SharePoint sees that no user credentials were provided in the request and an OAuth access token is present.  When acting on behalf of a user, the token will include user information, so the context will be the App+User context.


This is exactly the scenario I just described.  The App+User policy is applied, and both the user and the app must have sufficient permission to write to the list.


Have a good day, :)

Tuesday, September 15, 2015

How to use Node, Bower and Gulp with Visual Studio 2013

How to use Node, Bower and Gulp with Visual Studio 2013


Microsoft annouced (https://www.visualstudio.com/en-us/news/vs2015-vs.aspx#JavaScript) that Visual Studio 2015 and ASP.NET 5 will using Bower and Gulp

Note: ”Integrated tooling for client-side Web development using NPM, Grunt/Gulp, and Bower, including package management integration and the new Task Runner Explorer.

This means that packages like Bootstrap, jQuery,  and Angular will no longer be referenced using NuGet. NuGet is a great package manager for .NET libraries and the Microsoft eco-system. The web however, is much larger than Microsoft. The web development world has largely settled on Bower as the defacto package manager for client side libraries. It is not right to expect a developer who creates a new JavaScript library to publish their library as a NuGet package

Here is a step-by-step guide to using Bower with Visual Studio 2013 and  the ASP.NET MVC 5 template as an example.

The following steps you should make to reach the goal J:

Step 1 – Install NodeJS
Step 2 – Isntall Bower
Step 3 – Install Git
Step 4 – Initializing Bower for a ASP.NET MVC project template
Step 5 - Replacing Nuget Packages with Bower Packages
Step 6 – Move files from “bower_components” folder to project “Scripts” folder
Step 6.1 – Installing and initializing a project for Gulp
Step 6.2 – Remove NuGet Packages from the MVC project
Step 7 – Change referencing Scripts and Styles
Conclusion


Article

Step 1 – Install NodeJS

It is most important tool, you need to have on your development environment. We will use NPM command line tool to isntall other thing, like bower, gulp and etc
To install Node - simply visit http://nodejs.org and then click “Install”. Once your download completes, run that application and you should be all ready to go. The Node installer also includes npm, which we will use to install bower and gulp.

Step 2 – Isntall Bower

Install bower using the node package manager (npm). Open the command line and run

npm install bower -g

Step 3 – Install Git

Bower uses git to download packages from github. Specifically, you will need to install msysgit (https://git-for-windows.github.io/) and select the “Run Git from the Windows Command Prompt” option.




Step 4 – Initializing Bower for a ASP.NET MVC project template

I have created a demo test MVC project using standard VS2013 template


1.       Open “Command Promt” and navigate to the project folder.

2.       Run “bower init” command in the project folder:



3.       Answer question to create a bower.json file. Note: The only setting you need to take an attention marking the project as private to avoid accidentally publishing a project to the public bower registry.

4.       Go to Solution Explorer and Add Existing items to the project. Now you should have bower.json file in the project folder


Step 5 - Replacing Nuget Packages with Bower Packages

If you look at “Script” foder and BundleConfig.cs file “ App_start” folder, you will see, that by default, a MVC 5 project template references jQuery, jQuery Validation, Bootstrap and Modernizr. So we need to replace references to be used with Bower.






Let’s try to add “jQuery” using Bower. Bower packages are installed from the command line using the bower install.

1.       Bower packages are installed from the command line using the bower install. Open the project folder and ran the following command:

bower install jquery --save


2.       Install the remaining packages. Also  install RespondJS. This is a responsive design polyfill that is included in the Nuget bootstrap package, but is not included in the bower package.

               bower install jquery-validation --save
bower install jquery-validation-unobtrusive --save
bower install modernizr --save
bower install bootstrap --save
bower install respond-minmax --save


3.       All  javascripts components installed in the bower_components folder. The bower.json file describes all the client side packages that our project depends on. If you open bower.json file you will see the list of instal

{
  "name": "UsingBowerAndGulpWithVS2013",
  "version": "1.0.0",
  "description": "Demo project",
  "keywords": [
    "Bower",
    "Gulp",
    "and",
    "VS2013"
  ],
  "authors": [
    "AP"
  ],
  "license": "MIT",
  "dependencies": {
    "jquery": "~2.1.4",
    "jquery-validation": "~1.14.0",
    "jquery-validation-unobtrusive": "~3.2.3",
    "modernizr": "~2.8.3",
    "bootstrap": "~3.3.5"
  }
}

Step 6 – Move files from “bower_components” folder to project “Scripts” folder

A “bower_components” folder contains much more then it is needed for a project. It is better to copy only the files we need to a known location and reference them from there. But you can just include bower “bower_components” folder into the project root. If you want to copy files from “bower_components” to another folder  can use  a client side build system like Grunt or Gulp. I prefer to work with Gulp.

Step 6.1 – Installing and initializing a project for Gulp
1.       Install Gulp

Install gulp using the npm from the command line and run

npm install gulp -g         

2.       Initializing a project for Gulp

Create a package.json file in the root directory of the your project. do this by running npm init on the command line or simply creating a file with the following contents

npm init
                             


3.       Add package.json file to the project using “Add existing item…” in solution explorer.




4.       Install a packages that will be used for this project. Run the following commands from the same folder that you added the package.json file

npm install gulp --save-dev
npm install gulp-concat --save-dev
npm install gulp-uglify --save-dev
npm install del --save-dev 
npm install gulp-bower --save-dev 
npm install gulp-minify-css --save-dev
npm install gulp-copy --save-dev
npm install gulp-sourcemaps --save-dev
 

Note: the “–save-dev” option tells node to add these packages to a devDependencies section in the package.json file and install the packages in a node_modules folder in the current folder . At any time, you or another developer on your team can re-install all the devDependencies by simply running npm install.

5.       Create a gulpfile.js file in the project root folder and copy the following code snippet


Code snippet
///
// include plug-ins
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var del = require('del');
var minifyCSS = require('gulp-minify-css');
var copy = require('gulp-copy');
var bower = require('gulp-bower');
var sourcemaps = require('gulp-sourcemaps');

var config = {
    //JavaScript files that will be combined into a jquery bundle
    jquerysrc: [
        'bower_components/jquery/dist/jquery.min.js',
        'bower_components/jquery-validation/dist/jquery.validate.min.js',
        'bower_components/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js'
    ],
    jquerybundle: 'Scripts/jquery-bundle.min.js',

    //JavaScript files that will be combined into a Bootstrap bundle
    bootstrapsrc: [
        'bower_components/bootstrap/dist/js/bootstrap.min.js',
        'bower_components/respond-minmax/dest/respond.min.js'
    ],
    bootstrapbundle: 'Scripts/bootstrap-bundle.min.js',

    //Modernizr
    modernizrsrc: ['bower_components/modernizr/modernizr.js'],
    modernizrbundle: 'Scripts/modernizer.min.js',

    //Bootstrap CSS and Fonts
    bootstrapcss: 'bower_components/bootstrap/dist/css/bootstrap.css',
    boostrapfonts: 'bower_components/bootstrap/dist/fonts/*.*',

    appcss: 'Content/Site.css',
    fontsout: 'Content/dist/fonts',
    cssout: 'Content/dist/css'

}

// Synchronously delete the output script file(s)
gulp.task('clean-vendor-scripts', function (cb) {
    del([config.jquerybundle,
              config.bootstrapbundle,
              config.modernizrbundle], cb);   
});

//Create a jquery bundled file
gulp.task('jquery-bundle', ['clean-vendor-scripts', 'bower-restore'], function () {
    return gulp.src(config.jquerysrc)
     .pipe(concat('jquery-bundle.min.js'))
     .pipe(gulp.dest('Scripts'));
});

//Create a bootstrap bundled file
gulp.task('bootstrap-bundle', ['clean-vendor-scripts', 'bower-restore'], function () {
    return gulp.src(config.bootstrapsrc)
     .pipe(sourcemaps.init())
     .pipe(concat('bootstrap-bundle.min.js'))
     .pipe(sourcemaps.write('maps'))
     .pipe(gulp.dest('Scripts'));
});

//Create a modernizr bundled file
gulp.task('modernizer', ['clean-vendor-scripts', 'bower-restore'], function () {
    return gulp.src(config.modernizrsrc)
        .pipe(sourcemaps.init())
        .pipe(uglify())
        .pipe(concat('modernizer-min.js'))
        .pipe(sourcemaps.write('maps'))
        .pipe(gulp.dest('Scripts'));
});

// Combine and the vendor files from bower into bundles (output to the Scripts folder)
gulp.task('vendor-scripts', ['jquery-bundle', 'bootstrap-bundle', 'modernizer'], function () {   
  
});

// Synchronously delete the output style files (css / fonts)
gulp.task('clean-styles', function (cb) {
    del([config.fontsout,
              config.cssout],cb);
});

gulp.task('css', ['clean-styles', 'bower-restore'], function () {
    return gulp.src([config.bootstrapcss, config.appcss])
     .pipe(concat('app.css'))
     .pipe(gulp.dest(config.cssout))
     .pipe(minifyCSS())
     .pipe(concat('app.min.css'))
     .pipe(gulp.dest(config.cssout));
});

gulp.task('fonts', ['clean-styles', 'bower-restore'], function () {
    return
    gulp.src(config.boostrapfonts)
        .pipe(gulp.dest(config.fontsout));
});

// Combine and minify css files and output fonts
gulp.task('styles', ['css', 'fonts'], function () {
   
});

//Restore all bower packages
gulp.task('bower-restore', function() {
    return bower();
});

//Set a default tasks
gulp.task('default', ['vendor-scripts', 'styles'], function () {

});



6.       Run “gulp” command from the command line and you should see  output stating that scripts task is completed successfully.

Step 6.2 – Remove NuGet Packages from the MVC project

Uninstall-Package Bootstrap
Uninstall-Package jQuery
Uninstall-Package Respond
Uninstall-Package Modernizr
Uninstall-Package Microsoft.jQuery.Unobtrusive.Validation
Uninstall-Package jQuery.Validation

The Script folder is now cleaned up and only containing the files that are generated as output from the gulp build.

Step 7 – Change referencing Scripts and Styles

1.       change the way the project is referencing the script and css files. In Views\Shared\_Layout.cshtml change the following in the head tag

From
To
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
<link rel="stylesheet" href="~/Content/dist/css/app.min.css">
<script src="~/Scripts/modernizer-min.js"></script>


At the bottom of the page, change the following

From
To
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
<script src="~/Scripts/jquery-bundle.min.js"></script>
<script src="~/Scripts/bootstrap-bundle.min.js"></script>

2.       Remove any reference to the jquery validation bundle since we included those scripts in the jQuery bundle.

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

3.       To complete the clean-up process, delete the App_Start/BundleConfig.cs file and remove the call to RegisterBundles from Global.asax.cs.
Conclusion

The application now uses Bower  references to client side libraries and Gulp that generates bundles. Bower is large client code packages library, which is up-to-date by a client side developers. Many  client side packages are not available on Nuget and many developers might have nothing to do with the Microsoft ecosystem and expecting them to learn it so we can use their package is just not a good point. Recently on 20 July 2015 Microsoft released Visual Studio 2015 officially supports Gulp, Bower and NPM and has integrated tools for client-side Web development using NPM, Grunt/Gulp, and Bower, including package management integration and the new Task Runner Explorer. So if you have an access to the latest Visual Studio, it is better to use it, but, anyway, if you don’t have it, you can still use VS2013 and configure tools to work with Bower and Gulp

Friday, September 11, 2015

SharePoint Online: How To restore deleted items from Recycle bin with PowerShell.

If a SharePoint online user has deleted a huge amount of folders and files, he had in Document Library by chance, you can write a powershell script to restore it, instead do it manaully.

The script I have written can be fouund above on GitHub.


GitHub:

The script takes the following params:
  1.      Site collection administrator
  2.  User name who deleted files
  3.    Site collection url
  4.     Timestamp of items deleted date (ex., strart 2015-09-03 00:00:00 and end date 2015-09-03 23:59:59)



The script does the following actions:

  1. Takes  all site collection Recycle bin items and assign it into an array variable
  2.  It sorts an array in descending using merge method (https://gallery.technet.microsoft.com/scriptcenter/Merge-Sort-for-PowerShell-e5fdf3ab) (the first record in the last deleted)
  3. Limit deleted items count to the start date you enter in the script (ex. If recycle bin contains 8000 items from 2015-06-01 till 2015-09-09 and you want to restore items deleted for one particular day 2015-09-03, the items count will be limited to the start date)
  4.  Checks if deleted item is equal to timestamp
  5. Checks the user you entered in input
  6. Creates CSV report with sorted and deleted by the user items
  7.   Restores deleted items one by one from $csvReport filtered and sorted array with following methods

                                     $_.DeletedItem.Restore()
                                     $ctx.ExecuteQuery()
NOTE

      i you wish to get a report first to see what items will be restored first, just you need to comment the line with


                          $_.DeletedItem.Restore()
                           $ctx.ExecuteQuery()

and look at report.csv file in c:\tmp folder


The powershell script was created for a particular case, when the user deleted 25 GB of files stored on local drive via OneDrive and files were synhronized with SharePoint library. Files were deleted extremly fast and in one mass transaction. In this case, it was very important to get data in right order and hierarhy, as a Document libary has a lot of  nested folders and files . So you can takes the script as an example and modify it for your own case and a needs.

 Here a small example of Document library folder structure:





So have a nice day, J
I hope it will help somebody
Best regards,
Aleks