1

I have many levels of user permissions in my site.

So a junior user can NOT do things that a senior user can do. ( there are many levels of users. senior vs junior is just for simplification).

In addition to a server side validation for who is the user and what he can/t do — I also want NOT to provide the Javascript function registration at first place . (So if a user is a junior user , then his JS files should not contain JS functions of a senior user.)

Example :

The site has a general add javascript function which should appear to all users:

function add() {
    console.log("Add");
}

Junior users has higher privilege so they can ALSO do subtract . so their JS files include the subtract method:

function substract() {
    console.log("substract");
}

A general users won't have this substract method

Senior users has higher privilege so they can ALSO do power. so their JS files include the power method :

function power() {
    console.log("power");
}

A senior user won't have this power method

OK

According to this answer :

Note that you must have a separate bundle per page. You should not modify one and the same bundle on the fly....etc...

So , I created ( for now) 2 bundles , one for each page :

bundles.Add(new ScriptBundle("~page1Junior").Include(
                      "~/Scripts/General.js", "~/Scripts/Junior.js"));

bundles.Add(new ScriptBundle("~page1Senior").Include(
                      "~/Scripts/General.js", "~/Scripts/Senior.js"));

And then I take the relevant bundle according to some login and use :

<script src='@Scripts.Url("~/page1Senior (or) Junior")' async> </script>

Question

This seems like a wrong way to go.

If I have 10 pages and 10 user levels , According to that approach , I will need 100 different bundles.

what is the right way of serving appropriate js files for their relevant user permissions ?

Pseudo code of what i'm after :

user level       js files(combined to one)
------------|-------------
    1            [a,b]
    2            [a,b,c]
    3            [a,b,c,d]
    4            [a,b,c,d,e]

So If a user level 3 is logged on , then a single abcd.js JS file should be served ( minified).

Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Why would you have one bundle per page? That by itself would probably not be a good thing for performance. – usr Sep 08 '15 at 11:49
  • @usr I didn't say it. I was [referencing](http://stackoverflow.com/questions/11580274/visual-studio-2012-conditional-bundling/11658390#11658390) to an answer which states that claim.I'm Open to New Ideas – Royi Namir Sep 08 '15 at 11:50
  • Put the bundles on your layout then you wont need to have it on every view – heymega Sep 08 '15 at 11:56
  • @heymega Still , what about the glue between user and the specific JS's files ? can you post an example which will be clear not to me but also for readers ? – Royi Namir Sep 08 '15 at 12:00
  • "page1Junior" and "page1Senior" is just the names of bundles. They are created once on application start and can be used in any number of pages. So if you name your bundle "General+Junior" you can use it in any page. How do you conclude you need 100 bundles? – George Mamaladze Sep 08 '15 at 12:12
  • @achitaka-san Re-reading your comment , it does make sense. I just need to create a level bundle ( general+user).... – Royi Namir Sep 08 '15 at 12:16

1 Answers1

3

One way is to use DynamicBundleFolder

If you can have a directory structure like

Scrtips
-- /Permissions
   -- /1
      -- a.js
      -- b.js
   -- /2
      -- a.js
      -- b.js
      -- c.js
   -- /3
      -- c.js
      -- d.js

where 1,2,3 are the restriction levels, then in your RegisterBundles add a DynamicBundle

bundles.Add(new DynamicFolderBundle("userScripts", "*.js",new JsMinify()));

And then in your _layout.cshtml, you can do

@{
    var userPermissionLevel = 2; // grab your user permission level, from session maybe
}

@Scripts.Render("~/Scripts/Permissions/"+ @userPermissionLevel +"/userScripts")

and that will render all the scripts in that directory. You dont have to create bundles for each page then. And if you need to add new permission based file, just add to respective permission folder.

Update: This will work fine if you have unique js files for each permission level. For shared files, updating them will be quite a work. So what you can do is create bundle according to permission levels like

    // Bundle for permission level 1
    bundles.Add(new ScriptBundle("~/bundles/permissions/1").Include(
                            "~/Scripts/a.js")
                            .Include("b.js"));

    // Bundle for permission level 2
    bundles.Add(new ScriptBundle("~/bundles/permissions/2").Include(
                            "~/Scripts/b.js")
                            .Include("c.js"));

   // and so on for each level 3,4,5 include specific level files

and then again you can add them to page throught _layout.cshtml

@{
   var userPermissionLevel = 2; // grab your user permission level, from session maybe
 }

@Scripts.Render("~/bundles/permissions/"+userPermissionLevel)
Dandy
  • 2,177
  • 14
  • 16
  • There's also a great explanation [here](http://www.konstrui.nl/en/about-us/blog/daniel-plomp/2014/04/02/implement-the-microsoft-optimization-framework-into-dynamicweb). it's all about SUFFIXs. – Royi Namir Sep 08 '15 at 12:59
  • There is still a problem here because of multiple cloned files ... For example : A.JS should not appear many times – Royi Namir Sep 08 '15 at 17:37
  • @RoyiNamir yes you are right. This solution will work best if you have unique js files for each permission level. If you have shared js files, then managing them will be quite a work. – Dandy Sep 08 '15 at 18:49
  • Thanks for your edit . Regarding the dynamic bundle , I think it's still can be made like you suggested .but first I need to take control over the order of script addition . Would you mind having a look here ?http://stackoverflow.com/q/32474440/859154 – Royi Namir Sep 09 '15 at 18:04