Saturday 27 April 2013

Force application to run with elevated permissions. Run as Administrator (UAC)

I've been working for a bit on a application that hosts its own wcf service, too long to explain here, but the interesting point is that in order for the web service to be locally hosted, I need to run the app using elevated permissions, which is done very easily by adding a manifest file to the application.

This is the manifest file that you need:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
    </application>
  </compatibility>
</asmv1:assembly>

You can add this file from Visual Studio and just customize to the required permission level.

Monday 22 April 2013

Encoding issues with HTMLAgility pack ’

I've been using the HTMLAgility pack for a while and I've never had any encoding issues before but recently I've been seen loads of encoding issues, where this ' is encoded as ’ or " is encoded as “

There is a very simple solution, instead of simply loading the document like this:

doc.Load(file.ToString());

The encoding should be specified, like this:

doc.Load(file.ToString(),System.Text.Encoding.UTF8, false);

After loading the document having specified the encoding, all the encoding issues disappeared as if by magic :)

Wednesday 17 April 2013

Sort sitemap alphabetically according to Display name in MS Dynamics CRM 2011

A handy little class to sort a sub area of the sitemap in alphabetical order according to Display name rather than logical name.  Major Area refers to Workplace, Settings, etc.. whereas minor Area refers to the sub areas inside this, e.g. extensions.

I think it should be possible to do them in reverse alphabetical order by using the reverse() method when selecting the items, but I haven't tried. Not sure what kind of customer would want reverse alphabetical order though, as it seems counter intuitive, but there you go.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;

public class SitemapSorter
{
    [ThreadStatic]
    private IOrganizationService service;

    public SitemapSorter(IOrganizationService service)
    {
        this.service = service;
    }

    public void Sort(string file, string majorArea, string minorArea)
    {
        XDocument xdoc = XDocument.Load(new StreamReader(file));

    //Get XElements in the relevant area (Workplace -> Extensions in this case)
    //Store them in a Dictionary. key is the Display name and the value is the
    //entire node (XElement).
    var nodes = xdoc.Root.Descendants("Area")
        .Where(x => x.FirstAttribute.Value == majorArea)
        .Descendants("Group")
        .Where(x => x.FirstAttribute.Value == minorArea)
        .Descendants()
        .ToDictionary(x => RetriveDisplayName(service, x.LastAttribute.Value), x => x);
              
    //Use a Sorted Dictionary, which will automatically sort on key,not on value.
    SortedDictionary<string, XElement> items = new SortedDictionary<string, XElement>(nodes);
              
    //Remove the nodes from sitemap document
    xdoc.Root.Descendants("Area")
       .Where(x => x.FirstAttribute.Value == majorArea)
       .Descendants("Group")
       .Where(x => x.FirstAttribute.Value == minorArea)
       .Descendants().Remove();
              
    //Now add them in order
    xdoc.Root.Descendants("Area")
       .Where(x => x.FirstAttribute.Value == majorArea)
       .Descendants("Group")
       .Where(x => x.FirstAttribute.Value == minorArea)
       .First().Add(items.Select(x => x.Value));

    xdoc.Save(file);
    }

    private string RetriveDisplayName(IOrganizationService service, string entityName)
    {
    string result = string.Empty;
    try
    {
        RetrieveEntityRequest request = new RetrieveEntityRequest()
        {
            EntityFilters = EntityFilters.Entity,
            LogicalName = entityName
        };
        RetrieveEntityResponse response =
            (RetrieveEntityResponse)service.Execute(request);
        result = response.EntityMetadata.DisplayName.UserLocalizedLabel.Label;
    }
    catch (Exception ex)
    {
        CommonHelper.LogException(ex);
    }
    return result;
    }
}

Friday 12 April 2013

Use AppPool (Application Pool) credentials for Sharepoint integration

I had some fun today trying to work out how to use the AppPool Credentials for integration between our website and SharePoint.

So this is what I did.

using System.Security.Principal;

public class ImpersonateUser : IDisposable
{
  WindowsImpersonationContext ctx = null;
  WindowsImpersonationContext appPoolctx = null;

  public void ImpersonateAppPoolUser()
  {
     //RevertToSelf
     ctx = WindowsIdentity.Impersonate(IntPtr.Zero);
     // and call impersonate on the app pool user object
     appPoolctx = WindowsIdentity.GetCurrent().Impersonate();
  }

  public void UndoUserImpersonation()
  {
     if (ctx != null)
     {
        ctx.Undo();
        ctx = null;
     }

     if (appPoolctx != null)
     {
        appPoolctx.Undo();
        appPoolctx = null;
     }

  }

  public void Dispose()
  {
      UndoUserImpersonation();
  }
}

I used this class for SharePoint integration, as it seemed a quicker and simpler option than storing credential in the web.config and then encrypting.

using (ImpersonateUser ie = new ImpersonateUser())
{
    ie.ImpersonateAppPoolUser();

    using (ClientContext clientContext = new ClientContext(url))
    {
     //Get documents from SharePoint
    }
}

Sunday 7 April 2013

Applying CSS classes in ASP.NET MVC fields

I'm a total newbie when it comes to ASP.NET MVC and a few days back I was looking at issue where the font size was different on two text controls on the same form. One of the controls was a single line text box, while the other was

This is the original code, which I thought would apply the fields class to the controls:

<fieldset>              
   <div class="label">              
     @Html.LabelFor(model => model.Title)              
   </div>              
   <div class="field">              
     @Html.EditorFor(model => model.Title, new { autocomplete = "off" })          
     @Html.ValidationMessageFor(model => model.Title)              
   </div>              
   <div class="label">              
     @Html.LabelFor(model => model.Details)              
   </div>              
   <div class="field">              
     @Html.TextAreaFor(model => model, new { rows=10, cols=50 })            
     @Html.ValidationMessageFor(model => model.Details)              
   </div>              
</fieldset>              

The problem was that this wasn't working and I couldn't work out why. After looking at the styles one too many times, hangs head in shame, I realized that it was picking up the styles from the user agent rather than the css file.

A bit of searching revealing that this is what I should have done instead:

<fieldset>              
   <div class="label">              
     @Html.LabelFor(model => model.Title)              
   </div>              
   <div class="field">              
     @Html.EditorFor(model => model.Title, new { autocomplete = "off", @class=editor })              
     @Html.ValidationMessageFor(model => model.Title)              
   </div>              
   <div class="label">              
     @Html.LabelFor(model => model.Details)              
   </div>              
   <div class="field">              
     @Html.TextAreaFor(model => model,10,50, new {@class=editor })            
     @Html.ValidationMessageFor(model => model.Details)              
   </div>              
</fieldset>              

Tuesday 2 April 2013

Scripted Install of Joomla 3.0 in Centos/RHEL 6.x

Joomla 3.0 was released a little while back so I thought I would write a new post showing how to install it, but it turns out that my previous post works just as well, so I'll just link to it.

Install Joomla

At the time of writing this is the latest version of Joomla.

I have written a script to automate the installation on a new server, see below.

It's not the best script ever but it seems to do the job.

Assuming you call the script joomlainstaller.sh, you should invoke it like this:
joomlainstaller.sh "http://joomlacode.org/gf/download/frsrelease/17965/78414/Joomla_3.0.3-Stable-Full_Package.zip" Joomla JoomlaUser Password

Don't forget to make your script executable with the folliwubg command:
chmod +x joomlainstaller.sh


#!/bin/bash

EXPECTED_ARGS=4
E_BADARGS=65

if [ $# -ne $EXPECTED_ARGS ]
then
  echo "Usage: $0 JoomlaZipUrl Joomladbname Joomladbuser Joomladbpass"
  exit $E_BADARGS
fi

S1="Create database if not exists $2;"
S2="CREATE USER '$3'@'localhost' IDENTIFIED BY '$4';"
S3="GRANT ALL PRIVILEGES ON '$2'.* TO '$3'@'localhost' IDENTIFIED BY '$4';"
S4="Flush privileges;"

SQLCMD = "${S1}${S2}${S3}${S4}"

echo -e "Install the Web Server\n"

yum groupinstall "Web Server"  -y

echo -e "Install the MySQL\n"

yum groupinstall "MySQL Database server" -y

echo -e "Install the PHP and few others\n"

yum install man wget php php-mysql unzip policycoreutils-python -y

mkdir joomlainst

filename=$(basename "$1")

echo -e "Get $filename from $1 \n"

wget $1

echo -e "Unzip $filename and move\n"

unzip $filename -d joomlainst
mv joomlainst/* /var/www/html

echo -e "Start MySQL Service\n"

service mysqld start; chkconfig mysqld on

/usr/bin/mysql_secure_installation

echo -e "Create $2 Database and user $3 MySQL Service\n"

mysql -u root -p -e "$SQLCMD"

echo -e "Open port 80 on Firewall\n"

iptables -I INPUT -p tcp --dport http -j ACCEPT ; service iptables save

echo -e "Turn output buffering off\n"

sed -i 's/output_buffering = 4096/output_buffering = Off/g' /etc/php.ini

echo -e "Create Joomla config file\n"

touch /var/www/html/configuration.php
chmod 666 /var/www/html/configuration.php

echo -e "Start Apache\n"

service httpd start; chkconfig httpd on

echo -e "Disable SELinux"

setenforce 0
sed -i 's/=enforcing/=disabled/' /etc/selinux/config