One of the latest features added to Umbraco v5 is a new and improved permissions model. The more I play with this system, the more I realize how powerful it really is. So, in this blog post, I aim to tell you why permissions in v5 rock! =)

NB: Permissions were introduced in Alpha 3, however some of the features listed below are currently only available in the nightly builds.

More Types
In Umbraco v4, if you ever looked at the permissions grid, you’ll notice that each permission related to a context menu item in the content tree. So in v4, permissions basically allowed you to see or not see a specific menu item. In v5, we continue to support this mechanism, but we also allow none menu item related permissions aswell, which pretty much allows us to everything else detailed in this article.

Better Integration
In v5, we not only block access to menu items, but we can also block direct access to the associated controller actions, so even if someone jumps to an editor screen directly, they still can’t get access.

In addition, we also support toolbar buttons to require permissions, which means users only get to see the buttons they have permission to see. Don’t have the publish permission? then you don’t see the publish button =)

And finally, permissions in v5 work with all hive providers, meaning any tree using a hive provider for it’s data source now supports permissions (protected media anybody?), including third party providers. With this addition, it means permissions are no longer just the domain of the content tree.

Multi-User Group Support
In v4, users could only belong to one User Group, meaning that you could end up creating a lot of User Groups with a lot of cross over, just so you could get the right permission level you wanted for a user. Well, in v5, we now have Multi-User Group support, which means a user can now belong to multiple user groups at once. This means you can maintain fewer, more focused user groups, and just add users to, or remove users from, those groups as needed. And if there is any explicit overlap with any given permission, a “Deny” permission, will always take presidence over an “Allow” permission.

Improved UI
We haven’t just looked at the permissions functionality, but also how we go about setting permissions. In v5 we introduced a new permissions grid to make it simpler to see what is going on. On any node in the tree, you can click the permissions option and see the current nodes permissions. The new permissions grid can show you it’s inherited value, and allows you to override a value easily. Additionally, any changes are easily identifiable with the previous value taking on a grey background, and a little icon being added next to the permission name to signify a change.

Custom Permissions
And finally, as with most things in v5, Permissions are extendible. This means, package developers can introduce their own permissions. It’s as simple as creating a class that extends our base permission class, then just use our UmbracoAuthorize attribute on any menu items, controller actions or toolbar buttons you want protected.

Well that’s about it as it stands today, but we are looking to push permissions even further, for example, in the future we’d like to add the possibility of adding permissions to EntitySchemas thus allowing us to allow / deny access to specific properties of an entity.

So hopefully you now see some of the improvements in the permissions model in v5, and how these improvements make the whole system more secure and extendible. And as always, if you do have any questions, don’t hesitate to leave a comment.

A little while ago I blogged about how I automate my package creation in Umbraco v4 using some custom MSBuild tasks I wrote. Since then, I’ve been lucky enough to join the Umbraco HQ and get some early exposure to Umbraco v5 (aka Jupiter). One of the changes in v5 is around how packages work, moving away from the proprietary package manifests used in v4, in favour of the standard NuSpec manifests used in NuGet packages. This means Umbraco packages are now just plain old NuGet packages.

With this change, I thought I’d have a go at updating my build scripts so that I can continue to automate the package creation process. After a quick search, I couldn’t find any specific MSBuild tasks for NuGet package creation, so I went and wrote some =)

So here is the updated process.

Prerequisites

As I’m using MSBuild, you’ll obviously need to have the .NET framework installed. In addition, you’ll need to download the NuGet.exe command line executable from Codeplex, and my custom MSBuild.NuGet.Tasks dll and targets file.

Project Structure

Now this is completely up to you, but for this example and for my own projects, this is the project structure I use.

  • Lib - Referenced 3rd party libraries
  • Src - Source code for your application
    • MyProject - Project folder
      • MyProject.proj - Project file
  • Tools - Build tools
    • MSBuildNuGetTasks - The NuGet MSBuild tasks
    • NuGet - The NuGet command line executable
  • MyProject.sln – The project solution file
  • Package.build.cmd - The command file for triggering the package build process
  • Package.build.xml - The package MSBuild script
  • Package.nuspec - The package manifest file

Package.nuspec

This is the manifest file for your package. The manifest is responsible for holding all the metadata about your package such as name, version and description aswell as listing the package files and, in the future, your package dependencies.

If you actually looked at the package manifest files in v4, then these will actually look pretty similar. The namespaces might have changed a little, but the function is exactly the same.

What follows is a demo manifest file.

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>MyPackage</id>
    <version>0.0.0</version>
    <title>My Package</title>
    <authors>Matt Brailsford</authors>
    <owners>Matt Brailsford</owners>
    <projectUrl>http://blog.mattbrailsford.com</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>My Package Description</description>
    <summary>My Package Summary</summary>
    <language />
  </metadata>
  <files />
</package>

Package.build.xml

This is the build script for the package, and is responsible for orchestrating the build process. This hasn’t actually changed that much from my original build script, with the only real difference being a different packaging task (the ManifestUpdate task has also been updated, but the signature is pretty much the same as before). The options on the pack task exactly match those of the pack command of the NuGet command line tool.

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Package">

  <!--
  	****************************************
  	* IMPORTS
	****************************************
  -->
  <PropertyGroup>
  	<MSBuildNuGetTasksPath>$(MSBuildProjectDirectory)\Tools\MSBuildNuGetTasks</MSBuildNuGetTasksPath>
  </PropertyGroup>

  <Import Project="$(MSBuildNuGetTasksPath)\MSBuild.NuGet.Tasks.Targets" />

  <!--
  	****************************************
  	* PROPERTIES
	****************************************
  -->
  <PropertyGroup>
	<PackageVersion>1.0</PackageVersion>
  </PropertyGroup>

  <PropertyGroup>
	<RootDir>$(MSBuildProjectDirectory)</RootDir>
	<BuildDir>$(RootDir)\Build</BuildDir>
	<PackageDir>$(RootDir)\Package</PackageDir>
	<ProjectDir>$(RootDir)\Src\Namespace.MyProject</ProjectDir>
  </PropertyGroup>

  <!--
  	****************************************
  	* TARGETS
	****************************************
  -->

  <!-- CLEAN -->
  <Target Name="Clean">
	<RemoveDir Directories="$(BuildDir)" Condition="Exists('$(BuildDir)')" />
  	<RemoveDir Directories="$(PackageDir)" Condition="Exists('$(PackageDir)')" />
	<MakeDir Directories="$(BuildDir)" />
  	<MakeDir Directories="$(PackageDir)" />
  </Target>

  <!-- COMPILE -->
  <Target Name="Compile" DependsOnTargets="Clean">
	<MSBuild Projects="$(ProjectDir)\Namespace.MyProject.csproj" />
  </Target>

  <!-- PREPAIRE FILES -->
  <Target Name="PrepairFiles" DependsOnTargets="Compile">
    <ItemGroup>
      <BinFiles Include="$(ProjectDir)\Bin\Namespace.MyProject.dll" />
      <ViewFiles Include="$(ProjectDir)\Views\*.cshtml" />
      <PackageFile Include="$(RootDir)\Package.nuspec" />
    </ItemGroup>
	<Copy SourceFiles="@(BinFiles)" DestinationFolder="$(BuildDir)\lib" />
	<Copy SourceFiles="@(ViewFiles)" DestinationFolder="$(BuildDir)\content\views" />
	<Copy SourceFiles="@(PackageFile)" DestinationFolder="$(BuildDir)" />
  </Target>

  <!-- MANIFEST -->
  <Target Name="Manifest" DependsOnTargets="PrepairFiles">
	<ItemGroup>
      <ManifestFiles Include="$(BuildDir)\**\*" Exclude="$(BuildDir)\Package.nuspec" />
    </ItemGroup>
	<ManifestUpdate
		ManifestFile="$(BuildDir)\Package.nuspec"
		WorkingDirectory="$(BuildDir)"
		Version="$(PackageVersion)"
	    Files="@(ManifestFiles)" />
  </Target>

  <!-- PACKAGE -->
  <Target Name="Package" DependsOnTargets="Manifest">
	<Pack NuGetExePath="$(RootDir)\Tools\NuGet\NuGet.exe"
		ManifestFile="$(BuildDir)\Package.nuspec"
		BasePath="$(BuildDir)"
		OutputDirectory="$(PackageDir)"
		Verbose="true" />
  </Target>

</Project>

Package.build.cmd

This is a simple command script and is responsible for triggering the build process. Again, this hasn’t changed greatly from before, with the only change being and update to the msbuild executable used.

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild.exe Package.build.xml

Conclusion

All in all, there haven’t been any huge changes to the script from before, with the majority of the changes being hidden away in the MSBuild tasks. Hopefully this will make it easier for people who used my script before to make the leap into v5. As an added bonus, since Umbraco packages in v5 are just plain old NuGet packages, these MSBuild tasks can actually be used for creating any other kind of NuGet packages aswell.

Happy packaging =)

On a few occasions now, I’ve been asked whether it’s possible for the Desktop Media Uploader for Umbraco package could be made to support custom folders, to which, unfortunatley, the current answer is no. Rather than explain the reasons why every time the question pops up, I just thought I’d write a quick blog post instead.

1. Umbraco media has no “Folder” concept
The first reason is that Umbraco doesn’t really have the concept of a “Folder”. In Umbraco Folders and Files are the same, they are all just Media Types with differing “allowed child media types”. Ok, so I could check all media types to see if they allow sub media types, but that leads me on to reason 2.

2. Desktop Media Uploads are created File first 
When uploading a file via Desktop Media Uploader, the server automatically works out what Media Type to create a media item based upon it’s extension. The problem with this is that that it’s not until the file is uploaded that you would be able to discover whether the file can actually be created in the desired location. By only supporting the “Folder” Media Type, we don’t have that problem, as the “Folder” type can handle all Media Types, or, if it can’t, we can be sure at a bare minimum it can support the “File” Media Type as a fall back. With a custom folder, it could be possible to have no fall back media type, leaving us no option to deny the upload and report an error.

3. Folders don’t exist
The final reason, and this is more to do with the actual uploading of folders, is the fact that folders don’t actually have any physical attributes to be able to discover how to handle them. With files, we can check the file extension, and decide how to handle it, but with folders, that’s not possible. Team this then with “File first” upload issue mentioned above, and you can really start to get into a mess. What if you upload a folder that is not allowed in that location? All files in that folder would fail, and it would require the user to then log in to the CMS and rectify the issue.

I’m pretty sure that these things may be possible to fix, but the point of Desktop Media Uploader has always been to suite the largest majority of Umbraco users, and to not over complicate the process. I have made it extendable by supporting custom Media Types for files, but in my honest opinion, supporting custom folders just isn’t worth the payoff.

That said, Desktop Media Uploader is an open source package, and users are more than welcome to look at implementing this themselves, and if anyone was to do this, I’d be more than happy to review the code and merge the changes in if feel they don’t compromise the current  functionality.

http://dmu4umb.codeplex.com/SourceControl/list/changesets

Happy uploading.

Follow

Get every new post delivered to your Inbox.