Skip to content

Add Extensibility to Plaster's Constrained Runspace #333

Closed
@bwright86

Description

@bwright86

Plaster is a good platform to scaffold content, and I have used it for building module templates. But recently I have been using it to scaffold application configuration data.

One shortcoming I have found is that Plaster uses constrained runspaces to perform the scaffolding. Correct me if I'm wrong, but this was to provide safety around what is essentially Invoke-Expression. The difficulty comes from trying to write clean code and turn comma separated strings into properly formatted output.

Example template files:

Test.json.txt
(This is the simplest way I could think to join comma separated strings into a JSON array.)

{
    "Key":  "Value",
    "Array":  [
        ""
<%
if ($PLASTER_PARAM_Param1) {
    $PLASTER_PARAM_Param1.split(",").trim().foreach({",`"$_`""})
}
%>
               ]
}

The resulting file is not well formatted, and has a blank element in the first position of the array:
Test.json

{
    "Key":  "Value",
    "Array":  [
        ""
,"Test"
,"Testing"
               ]
}

Another option is to use .Replace, and replace commas with newlines(`n) and double quotes ("). But newlines are not interpolated in the constrained runspace. So this doesn't work:

"`"$($PLASTER_PARAM_Param1.replace(",", "`"`n,`""))`""

Possible Solutions

One solution that I would like to see, is a configuration file that can be placed in a user directory (like $PROFILE), or in the module folder itself. This file contains a list of allowable cmdlets in the scaffolding process, and Invoke-Plaster adds these cmdlets to the runspace. This would provide the extensibility, without having to rebuild the module with a custom list of cmdlets. It also puts the security onus on the user that adds the commands. Either the installing user can add a config file, or only the current user's config file is used during scaffolding.

Another solution, is adding a parameter to the Invoke-Plaster function, like -AllowedCmdlets to add a list of cmdlets to be used during scaffolding. This makes it a little easier for the user to scaffold with the cmdlets they need, but on the flip-side it makes it easier to pass cmdlets required for command injection. So this provides a little less control when scaffolding content.

Either of these solutions would allow the code to be cleaner, like so:

{
    "Key":  "Value",
    "Array":  [
<%
if ($PLASTER_PARAM_Param1) {
    $output = $PLASTER_PARAM_Param1 -split ",") -join "`",`n`""
    "`"$output`""
} else {
    "`"`""
}
%>
               ]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions