How can i isolate Razor Views?
Asked Answered
C

4

5

Is there a way to expose Razor syntax and (custom) helpers to people , but say ... not allow them to create code blocks or , to only limit them in the usage of the helpers and to not give them the power to execute pure C# code in the views ?

Any ideas and pointers to similar solutions are welcome !

update:// I would like to give the users the power to write their own HTML and access only to a list of html helpers. Mostly the default ones and the ones i create.

For example i do not want them to be able to execute code within @{ //code } blocks and Also no using and @model ( not sure about this one) only have access to @Html.* @if else for foreach

or better yet , give them access only to specific namespaces (this just a thought tho)

update:// After some testing , i found out that RazorEngine does as close as to what i'm trying to do : run the views in isolated environment and add access to specific namespaces.

Clockwise answered 23/2, 2013 at 15:13 Comment(9)
please add examples of user activity allowed and its effect. should be at least 5 since it's hard to completely understand the scope of such an approach.Mallissa
updated. and what should be at least 5 ?Clockwise
your question is intriguing but difficult to fathom specifics. So give examples of code blocks you would want the user to be able to enter and code blocks you would not want them to be able to enterMallissa
I have updated my question , and any general pointers would be helpful too !Clockwise
This seems like a parsing problem. Take in the input in a TextArea. Check for certain patterns in the string, etc. Alternately, you can apply 'code building' strategy. Allow certain parts of the code to be chosen from a selectbox or dropdown and allow the params to be entered as free text. This is a first volley of ideas.Mallissa
Do you want them to be able to create an entirely new view using only the tags in question. Or do you want them to upload code sets to your site to add to existing views?Birl
I would want them to create new new views with he specified tagsClockwise
I'll go with Dave A take the input in text area and write a parser that identifies the not allowed keywords and simply pass the user syntax to the parser and manipulate the result according to your choiceFee
Mohsin, i'm kind off going that way , a mix between removing keywords and using RazorEngine to sandbox the views !Clockwise
H
2

There is a project called RazorEngine, built upon Microsoft's Razor, that allows you to parse that syntax without being in the context of returning an MVC view. Here's how it's used:

 string template = "Hello @Model.Name! Welcome to Razor!";
 string result = Razor.Parse(template, new { Name = "World" });

You can also specify a customized template base, which should allow you to define only the Html Helpers you want to expose to your users:

 Razor.SetTemplateBase(typeof(HtmlTemplateBase<>));

 string template = 
  @"<html>
      <head>
        <title>Hello @Model.Name</title>
      </head>
      <body>
        Email: @Html.TextBoxFor(m => m.Email)
      </body>
    </html>";

  var model = new PageModel { Name = "World", Email = "[email protected]" };
  string result = Razor.Parse(template, model);
Hygroscope answered 28/2, 2013 at 3:25 Comment(1)
the isolated templates in RazorEngine is just what i was looking for !Thanks!Clockwise
E
4

I would not recommend you doing that. There simply is not an easy and reliable way to give them this ability without compromising the security of your site. If you trust your users then you could do it. If you don't then a templating engine such as DotLiquid is something far more appropriate for this purpose.

Encarnalize answered 26/2, 2013 at 12:57 Comment(3)
Darin , i don't want to implement another template engine , i already have Razor and i want to leverage the awesome syntax it provides , and just limit what functions people can execute.Clockwise
Do you trust your users? It seems you don't because you are asking how to prevent them from doing certain actions. I am afraid that Razor was not designed for this purpose.Encarnalize
Thanks for highlighting DotLiquid, seems a great library for this purposeGurrola
P
2

you may try to change razor view engine and related classes to check for disallowed situations.

When source is generated (view engine generates a source file to compile ), you have to check it manually (by parsing c# or vb.net code). It is possible, but not feasible (really).

Even if you have managed to parse and check code, you have to identify your code (which is allowed) and customer code (which has restrictions).

At the end you have to accept the fact you can not really disallow anything other than using another template engine.

because

  1. Your customers will find a way to make their views look like yours.
  2. You cannot limit most basic required features like var r = new Random();
  3. You cannot estimate what most basic requirements are
  4. you cannot say No to your customers when they need to use their custom libraries

By the way, you may try another thing. Write a virtual path provider, and convert customer templates written in AviatrixTemplate when requested by runtime. By using this route, you still use razor engine, loose only a slight time when converting (it is one time only). But your AviatrixTemplate won't be hilighted, and you still need to check for disallowed code.

PS: a basic loop may give your users more then you want. for example following code allows creation of a class and call it for one time. they may use fully qualified class name or may use Activator.CreateInstance.

@for (var r = new Random(); r != null; r = null)
{
    @r.NextDouble()
}

just do not bother.

Platt answered 27/2, 2013 at 23:33 Comment(0)
H
2

There is a project called RazorEngine, built upon Microsoft's Razor, that allows you to parse that syntax without being in the context of returning an MVC view. Here's how it's used:

 string template = "Hello @Model.Name! Welcome to Razor!";
 string result = Razor.Parse(template, new { Name = "World" });

You can also specify a customized template base, which should allow you to define only the Html Helpers you want to expose to your users:

 Razor.SetTemplateBase(typeof(HtmlTemplateBase<>));

 string template = 
  @"<html>
      <head>
        <title>Hello @Model.Name</title>
      </head>
      <body>
        Email: @Html.TextBoxFor(m => m.Email)
      </body>
    </html>";

  var model = new PageModel { Name = "World", Email = "[email protected]" };
  string result = Razor.Parse(template, model);
Hygroscope answered 28/2, 2013 at 3:25 Comment(1)
the isolated templates in RazorEngine is just what i was looking for !Thanks!Clockwise
R
0

I have never done this before, but it sounds like you want to give users the ability to write code and have it compiled for use, yes?

If so, you may want to look into the CSharpCodeProvider class, the RazorTemplateEngine class and the System.CodeCom.Compiler namespace.

Have a look here for some information on those classes:

CSharpCodeProvider: http://support.microsoft.com/kb/304655

RazorTemplateEngine: http://msdn.microsoft.com/en-us/library/system.web.razor.razortemplateengine(v=vs.111).aspx

Roaster answered 26/2, 2013 at 13:3 Comment(2)
Hey , i don't want them to compile anything , just the ability to create templates and be able to use basic loops and html helpersClockwise
If this involves using code that you have written, you will need to compile their code in order for them to use your code. You can during the process filter out any unwanted namespaces etc... If you just want to mimic Razor, you will need to either compile the Razor or parse it yourself.Roaster

© 2022 - 2024 — McMap. All rights reserved.