Block access to the backend controller for non authenticated users
Adapt the actions that you get in the Umbraco back end by right clicking
Due to a very busy work schedule I didn’t had the time to look into this list. In the mean while version 6 was released by the Umbraco core team.
Last week I received the question if I had already found a solution for the first item on the todo list: blocking access to the backend controller for non authenticated users.
Between the search for Easter eggs together with my son, backing pancakes and nothing interesting on the TV this evening I found the time to implement the feature.
Reminder: the problem
A small reminder of the problem we are facing. We’ve created a MVC controller to access from the Umbraco backend to perform our own business logic like shown in the image below.
We used the implementation if the Umbraco’s Surface Controller that will create a MVC area. If we know the structure of the URL to this area – controller – action we can access the page without logging in the Umbraco backend.
This is off course a security risk we have to solve. We don’t want non authenticated users to be able to access our business logic.
Using the Authorization attribute
In ASP.NET MVC access to certain controllers or individual actions is managed by using the Authorization annotation attribute. You can use the default attribute where you are able to filter request based on specific users or specific user roles.
But you can off course inherit from the default attribute and implement your own authorization attribute.
Create the UmbracoAuthorizeAttribute
In this post I’ll extend the project we’ve created during the previous post and that you can find on Github.
Add a folder ‘Helpers’ in the UmbracoMVCDemo.BackEnd project. In that folder create a new class ‘UmbracoAuthorizeAttribute’. Add the public keyword to the class implementation and we shall inherit from the System.Web.MVC.AuthorizeAttribute.
Implementing your own authorization login can be done by overriding two methods from the base class: AuthorizeCore(HttpContextBase httpContext) and OnAuthorization(AuthorizationContext filterContext).
In AuthorizeCore(HttpContextBase httpContext) we will connect to the Umbraco backend to check if the user is authenticated or not.
I’ll first check if the httpContext contains any value, if not we’ll throw an exception. After that I’ll use a method from the Umbraco BasePage: ValidateUserContextID. This method will return true if the user is authenticated and false if not. With that result we’ll set a class variable we can use in the implementation of the OnAuthorization method.
In this implementation we’ll first execute the base class implementation before we check the failedAuthentication class variable. If the authentication in the failedAuthentication failed we’ll send the user to the login page using the FormsAuthentication class.
Adding authorization to our controller
It’s not enough to create the attribute, we still have to tell our controller to use the authentications we’ve implemented. Open up the DemoAdminSurfaceController class we created in the previous post and add the UmbracoAuthorize attribute (line 4).
I’ve opened up another browser and accessed the same action again. (keep in mind that we make use of the default FormsAuthentication that will use a session cookie. Therefor will a new tab in the same browser not give the desired effect). Because we’re not authenticated we get redirected to the login page.
You’ll see the url we entered in the ReturnUrl parameter. If we now enter our credentials we’ll get redirected to the Umbraco back end. Although the ReturnUrl is filled out we’ll not be redirected to the correct page. We still have to click on our demo Section and demo node.
I’ve had to alter the default web.config file to be correctly redirected to the login page. I’m not sure this needs to be done if you have a fresh installation, I’ll add it here to avoid bad redirections.
You can find the full source code from this post and the earlier posts on Github. Feel free to download, fork, comment, …
I saw a tweet from John Galloway (@jongalloway) coming by this evening that can interest any developer in the ASP.NET stack. It’s a draft of the features that Microsoft want to include in the next release of the stack.
There are no release dates and they do emphasize it’s a planning document but I like the way Microsoft is going with the open sourced ASP.NET stack.
For one of our projects where close to the first test release. While preparing the necessary documents (test overview, legal documents, bug report, …) I felt a bit ashamed to give the client a Word document to report bugs to us. For a software development company it’s a bit shameful to let the client fill out a paper, scan it, mail it and then have someone copy the document in our issue tracker.
While driving home I thought it couldn’t be that difficult to set up a small site where the client can report the bugs. But I didn’t want to create a new bug tracker nor give the client direct access to our issue tracker (JIRA from Confluence).
JIRA has a API that you can address to create and fetch issues from their tracker. But I didn’t want to spend a couple of hours implementing the REST service. (jeah, I know, lazy as hell)
Nuget to the rescue
When I got home, the first thing I checked was the nuget site to see if anyone had already created a package to communicate with the JIRA API. First thing that showed up in the search was Atlassian.SDK a complete package, even including a Linq Query implementation to search for issues created by Federico Silva Armas.
Great, let’s get started.
New MVC 4 web application
I fired up Visual Studio 2012 and choose a new MVC 4 Default application with Razor support. Opened up the Package Manager Console and ran the following command:
I added a new controller in the controllers folder and named it HomeController. In the Index method I’ve added the call to JIRA to fetch all items from a certain filter.
The implementation is really simple, create a new Jira object with as parameters the URL to your JIRA instance, a username and a password. (in the constructor) In the Index method you then can call GetIssuesFromFilter and add the filtername as parameter. The advantage of using a filter is that you can always change this filter settings if you want to remove certain issues from the result without to change anything in your application.
You’ll need off course the user rights correctly set in JIRA to access the issues that are returned from the filter.
Next I created a new view under the Views – Home folder using the add view action after a right click on the folder. Create a strongly-typed view by selecting the Atlassian.Jira class as Model class.
Click Add and the view is created.
If you hit F5 now, your browser should open up and you get already the overview screen for all issues returned from the filter you have selected.
In 10 minutes I’ve created a working (but ugly) web application that can fetch all the tickets I wanted to show to the customer. Of course your view will need some tweaking to show the values of the issues you want to be shown.
Adding a new issue
Adding a new issue to JIRA is as simply. (You can check the complete code on Github). I give you a (very) short overview.
Create 2 new methods Create in the HomeController. The first one just returned the view, the second one add the HttpPost attribute and this will receive an Atlassion.Issue object with all the values. Pushing this to JIRA is as simple to create a new issue object from the jira object and fill up the values. Hit SaveChanges on the jira object and your issue is created.
On thing I had a problem with is the projetc name – key difference in the jira.CreateIssue() method. I first tried with the project name but I got some HTML 500 error returning. Although for fetching issues this worked fine but for creating issues you apparently have to gibe the project key instead of the project name.
Look and feel
Ok, we have a working application but the look and feel isn’t that, certainly not enough to send to an end user. I didn’t wanted to spend to much time on the look and feel and decided to use the Twitter Bootstrap.
Don’t start downloading the package from the Twitter Bootstrap website. Instead use the nuget package manager again. There is a Bootstrap for MVC 4 package that will add all necessary items to your solution.
Open up the Package Manager Console again and run the following command:
Add bootstrap to the bundles
To add the bootstrap files to your application we’ve to alter the style and script bundles that are in use. Open up the BundleConfig.cs class in the App_Start folder. There we can add the necessary files to the bundles.
Online 28 I changed the the Content/css bundle to include the bootstrap css instead of the default Site.Css. On line 21 I added a script bundle to include the bootstrap.js file.
Because I added a script bundle we’ll have to add this bundle in the _ Layout.cshtml view.
Just underneath the rendering of the jQuery bundle add the rendering of the bootstrap bundle. (at the bottom of the view.
I was able to create an new interface for our client to report bugs in just an hour of two. (the above only took 30 min but I’ve added some extra logic to send emails and stuff). Off course it’s not correct to add all business logic in your controllers and to hard code some strings and stuff. For this small application it’s more then enough. Underneath the screenshots of the 2 pages (in Dutch).
You can find this project on Github, feel free to fork, comment, …
One note, to avoid adding my personal credentials to the project I’ve created an xml file that holds the credentials in the App_Data folder. When creating the Jira object I fetch the values from this file. For obvious reasons I added this file to the .gitignore so it wouldn’t be pushed to Github. The structure of the file:
For one of our projects we had to retrieve data from an external source and store them in a database. One of the requests from the client was to see the retrieved data in a graph. Furthermore, he wanted to see a live update every second of the retrieved data in that graph.
After some searching I found the OxyPlot library. This library can be used in WPF, Silverlight, Windows Forms and even in Windows Store apps. The are now working on a alpha release for Mono.
Although the package is already downloaded more then 10 000 times there are not so many blog posts to find about implementing the library.
Open op Visual Studio and start with creating a new WPF project. Choose a name and a location and hit ‘OK’.
After the project is created open up the Package Manager Console and type following commands at the prompt and hit enter (after every command):
You can of course use the Package Manager UI by right clicking References and choose Manage Nuget Packages and them that way.
Create the ViewModel
We’ll use the MVVM model (partial) to render the Graph on the screen. First step is to create the ViewModel for our MainWindow.xaml. Right click on the project and add a folder ViewModels. Right click the folder and add a class MainWindowModel.cs.
To use the MVVM model we need to make the class public and inherit the INotifyPropertyChanged interface.
NOTE: The OxyPlot WPF package doesn’t completely support the MVVM model. You can’t use only the OnPropertyChanged method to update the graph. You’ll still need the manually refresh the graph from the code behind class of the XAML page. I saw a post in the discussions on codeplex that they are looking to add complete MVVM model but are short of time at the moment. Maybe the next version will support it. To be complete I add the necessary steps to implement the MVVM model in this post.
After inheriting the interface we have to implement the PropertyChangedEventHandler event as shown below.
Now we can add some public properties that we’ll bind to in the XAML page. First create a PlotModel that’s part of the OxyPlot library. In the constructor we’ll initiate the PlotModel parameter. The setter will call the OnPropertyChanged method that will notify the view there is a change on the object that may have to be rendered.
Adding the graph to the page
We can now add the graph to the MainWindow.xaml page. Before we can add the graph we’ll need to add the namespace for the OxyPlot library (line 4). We’ll bind the PlotModel parameter to the PlotModel we’ve created in the view model.
Binding the model to the view
Last part for our setup is to bind the view model to the view. Because we don’t use any MVVM frameworks we’ll have to manually bind the model in the code behind of the MainWindow.xaml page.
Add a private property of our view model and initiate this property in the constructor. Point the DataContext to this property and we’re done.
If we hit F5 to run the application we’ll see an empty window opening. We have of course add some data to the PlotModel before the graph will be rendered.
Set up the Graph – PlotModel
Back to our view model to set up our view model. First start will be adding the axes for the graph so OxyPlot knows where to plot the points.
Create a new method SetUpModel in our view model class. In here we’ll define the legend of the graph (position, border, sire, …) and add 2 axis. A DateTimeAxis for our X-axis (we want to plot points in a line of time) and a ValuaAxis for our Y-axis.
The set up for the legend of the graph is self explanatory. At line 10 you’ll see the creation of the DateTimeAxis. We’ll choose the position of the axis, give it a name (Date) and a string format pattern how the date has to be displayed. Next to that we’ll add some parameters to show major and minor gridlines and the interval size. After creation we’ll add the axis to the PlotModel. The ValueAxis is similar initiated, only did we position the axis on the left side and tell the Axis to start at the value 0.
If we add a call to this method in the constructor of our view model and hit F5 again we’ll now see window opening that contains an empty graph.
Now we have our graph and are ready to add some graph lines to the PlotModel. In this post we’ll add four different lines that will be plot.
To avoid complexity I added a class Data.cs where the data is hardcoded. In a real life application you’ll be implementing a database call or a service invocation or a web API request, …
The data I’ll receive will be a List<T> of a new simple class I’ve created: Measurement. This class has 3 public parameters: a DetectorId (long), a Value (int) and a DateTime (DateTime). I’ve added 4 different detectors that each have 10 measurements of a random value between 1 and 30.
Add the data to the PlotModel
In the view model we’ll create a new method LoadData where we’ll get the data and add some code to plot all point on the graph.
After fetching the data I’ll use the LINQ GroupBy expression to create a IEnumerable with as key the DetectorId and a collection of Value and Datetime as values. (line 5)
This will allow us to loop over the result and then add a LineSerie per Detector. In the setup of the LineSerie we’ll set some properties like colors and line thickness and the title. (line 9 till 18).
After we’ve created the LineSerie we can add the points to the LineSerie. We make use of the DateTimeAxis builtin funtion to convert a date to a double and add the value (line 20).
After we added the points to the LineSerie we’ll still have to add the LineSerie to the PlotModel. (line 21).
And that’s it. Hit F5 and you’ll see that are graph will be rendered and that per detector a line will appear plotting the random values between 1 and 30.
Updating the graph real-time
For the second question of our client we had to add real-time updates. For this demo I’ll add an new measurement to the graph every second. The OxyPlot library will make sure our graph will move along every time we’ll add a new measurement.
I’ve added a static method in the Data.cs class that will return a random value a second after the DateTime parameter that will be send along. In the view model I’ve created a private parameter DateTime parameter (lasUpdate) that will hold the moment we last updated the graph.
Update the view model
We’ll add a new method to the view model UpdateModel. This time we’ll make it public so it can be called from the view as shown in the next chapter.
In the UpdateModel method we’ll fetch the data from out Data.cs class and perform the same grouping action as in the LoadData method.
This will allow us to fetch the data per detector. After retrieving the correct LineSerie we can add the points like we did in the LoadData method.
Update from the view
We don’t want the update of the model to initiate before the previous is completely rendered to avoid an exception that we are modifying a list while rendering the graph. Therefor we make use of a CompositionTarget.Rendering event. This event will be fired every time the view is done rendering.
In the constructor of the MainWindow.xaml.cs class we’ll attach an eventhandler on the Rendering event.
In the event handler we’ll call the update method from the view model. After that call we’ll have to tell the PlotModel that there was an update and that he has to refresh the graph (line 14). (This is where OxyPlot drifts away from the MVVM model).
Avoid to many updates
The rendering event is ideal to avoid exceptions but you’ll see to many updates per second to keep the graph readable. We can solve this to add a StopWatch in the code behind and only trigger the update when the last update is at least a second ago.
After adding the StopWatch we’ll see that every (for this demo 5 seconds) a new point is added to the graph.
As you can see, with OxyPlot you don’t need to write to many code to create real time updating charts.
OxyPlot has many more options and graph styles, they have provided a demo page where a variety of graphs are rendered in Silverlight. You can copy the source code with the keyboard combination Ctrl+Alt+C. If you want to copy the properties use Ctrl+Alt+R.
The source code of this post can you find on Github. Feel free to fork, download, …