Wednesday, 19 November 2014

SharePoint Online: How do I set the Web.AlternateCSS property in CSOM?

The properties are only exposed in the '16' (SharePoint Online) version of the client side dlls. You will need to change your references to point to

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll

and

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll

Tuesday, 18 November 2014

C#: How do I store a secure password?

The eternal problems of encryption and data security is an ever present headache for all developers.
This post provides a great introduction to the problem.

Fortunately, C# provides a very powerful Windows Data Protection API to resolve this issue.

Read more about it here and find the sample code here.

Here is a simple extension method to achieve the required result:

using System;
using System.Security.Cryptography;
using System.Text;

namespace MyProject.Security
{
 public static class SecurityExtensions
    {
        private const DataProtectionScope Scope = DataProtectionScope.CurrentUser;
        static readonly byte[] AdditionalEntropy = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };

        public static string Encrypt(this string plainText)
        {
            if (plainText == null) throw new ArgumentNullException("plainText");

            var data = Encoding.Unicode.GetBytes(plainText);
            var encrypted = ProtectedData.Protect(data, AdditionalEntropy, Scope);

            return Convert.ToBase64String(encrypted);
        }

        public static string Decrypt(this string cipher)
        {
            if (cipher == null) throw new ArgumentNullException("cipher");

            var data = Convert.FromBase64String(cipher);

            var decrypted = ProtectedData.Unprotect(data, AdditionalEntropy, Scope);
            return Encoding.Unicode.GetString(decrypted);
        }
    }
}

The usage would be as follows:

var plainPassword = "MyPassword";
var encryptedPassword = plainPassword.Encrypt();
var plainPasswordAgain = encryptedPassword.Decrypt();

This can also be moved to a PowerShell script:

namespace MyProject.Security
{
    // This class is used by the EncryptionHelper class to expose the encryptions methods

    public class SecurityHelper
    {
        public static string Encrypt(string plainText)
        {
            return plainText.Encrypt();
        }

        public static string Decrypt(string cipher)
        {
            return cipher.Decrypt();
        }
    }
}

function Get-EncryptedPassword
{        
[CmdletBinding()]        
Param(        
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]        
[string]$PlainPassword,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]        
[string]$DllDirectory
)    

$bytesCommon = [System.IO.File]::ReadAllBytes("$DllDirectory\MyProject.Security.dll")
$loadResultCommon = [System.Reflection.Assembly]::Load($bytesCommon)

return [MyProject.Security.SecurityHelper]::Encrypt($PlainPassword)
}

function Get-DecryptedPassword
{        
[CmdletBinding()]        
Param(        
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]        
[string]$EncryptedPassword,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]        
[string]$DllDirectory
)    

$bytesCommon = [System.IO.File]::ReadAllBytes("$DllDirectory\MyProject.Security.dll")
$loadResultCommon = [System.Reflection.Assembly]::Load($bytesCommon)

return [MyProject.Security.SecurityHelper]::Decrypt($EncryptedPassword)
}

This would be invoked as:

# get the directory of the dll.
$dir = Get-Location
# include the commandlets so they can be used
. .\<scriptName>.ps1
$cipher = Get-EncryptedPassword("P@$$W0rD")
$plainText = Get-EncryptedPassword($cipher)

Wednesday, 5 November 2014

C#: How do I generate a SecureString password?

There is a simple function to generate a secure string password:

            public static SecureString StringToSecure(string password)
            {
                var secure = new SecureString();
                foreach (char c in password)
                {
                    secure.AppendChar(c);
                }
                return secure;
            }

Tuesday, 4 November 2014

SharePoint Online: How do I brand my Sites, Subsites and OneDrive for Business Site?

The patterns for applying branding during site creation have changed, but fortunately, the Patterns and Practices team have provided some excellent guidance on how to resolve some common issues.

Here are some of the links I have found very useful:

Async site collection creation:

Sub site creation app:

OneDrive for Business:
https://github.com/OfficeDev/PnP/tree/master/Solutions/Provisioning.OneDrive