SPWeb.EnsureUser with elevated privileges

by Christian Fredh 3. januari 2010 00:07

When you work with groups and users and custom code in SharePoint you often use the SPWeb.EnsureUser method that according to MSDN documentation “checks whether the specified login name belongs to a valid user of the Web site, and if the login name does not already exist, adds it to the Web site”. The method returns an SPUser object.

The user who runs this method needs to be a site collection administrator and the user or group to resolve needs to come from an Active Directory source.

An alternative is to use SPWeb.SiteUsers[loginName] that also returns an SPUser object without requiring site collection administrator privileges. The issue you run into with using this property is that if the user haven’t logged in yet, the user will not be found, and that is why you want to use the EnsureUser method. But again, you need elevated privileges for this. EnsureUser actually uses the SiteUsers property for returning the user after adding it if needed.

Created a helper method for this purpose, that you might find helpful if working with users from the SharePoint object model. It is written as an extension method for the SPWeb class. It can easily be converted to a regular static method if not using C# 3.0 for SharePoint 2007 development.

public static class SPWebExtensions
{
    [CLSCompliant(false)]
    public static SPUser EnsureUserElevated(this SPWeb web, string loginName)
    {
        if (web == null)
            throw new ArgumentNullException("web");

        if (string.IsNullOrEmpty(loginName))
            throw new ArgumentException("Login name cannot be null or empty.", "loginName");

        using (SPSite elevatedSite = new SPSite(web.Site.ID, web.Site.SystemAccount.UserToken))
        {
            using (SPWeb elevatedWeb = elevatedSite.OpenWeb(web.ID))
            {
                // Allow unsafe updates required, throws exception without, if not administrator.
                elevatedWeb.AllowUnsafeUpdates = true;
                elevatedWeb.EnsureUser(loginName);
            }
        }

        return web.SiteUsers[loginName];
    }
}

As you can see the SiteUsers property is still used to return the user, to get the correct user context, if you afterwards use SPUser.ParentWeb.CurrentUser for example.

Here is how you would retrieve a user using the method:

string loginName = "SOMEDOMAIN\someLoginName";
SPUser user = SPContext.Current.Web.EnsureUserElevated(loginName);

Tags: , , , ,

.NET | .NET 3.5 | SharePoint | SharePoint 2007

The Enumerable Class – Range, Repeat and Empty

by Christian Fredh 3. oktober 2009 19:36

The Enumerable class was introduced in .NET 3.5 and lives in the System.Linq namespace and provides the LINQ extension methods. It also has three static methods that can be really useful, Range, Repeat and Empty that all returns a generic IEnumerable.

Range

The Range method provides a quick way of getting a sequence of integers in a specified range. Instead of writing something like this to get a collection of integers:

static IEnumerable GetSequence(int start, int count)
{
    List sequence = new List();
    for (int i = start; i < start + count; i++)
    {
        sequence.Add(i);
    }

    return sequence;
}

or:

static IEnumerable<int> GetSequence(int start, int count)
{
    for (int i = start; i < start + count; i++)
    {
        yield return i;
    }
}

and call the method with:

IEnumerable<int> sequence = GetSequence(1, 100);

you could just write:

IEnumerable<int> sequence = Enumerable.Range(1, 100);

Repeat

The Repeat method provides a quick way of getting a collection of one repeated value. Instead of writing something like this:

static IEnumerable<T> GetSequence<T>(T value, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return value;
    }
}

and call the method with:

IEnumerable<string> sequence = GetSequence<string>("My Repeat Value", 10);

you could just write:

IEnumerable<string> sequence = Enumerable.Repeat<string>("My Repeat Value", 10);

Empty

Ever wanted to get or return an empty collection? I know I have. Until I found this method I have used things like:

return new int[] {};

and:

return new List<int>();

or in some situations:

yield break;

Using yield break has a major drawback that it cannot be used in catch blocks as described by Eric Lippert.

But the Empty method provides a clear and descriptive way of getting an empty collection of any type. Just write:

return Enumerable.Empty<int>();

Tags: , ,

.NET | .NET 3.5 | LINQ

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About Christian Fredh

Christian Fredh

A twenty six year old solutions architect and developer living in Stockholm, Sweden. I work as a SharePoint consultant at Avega Group with .NET and SharePoint development.

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view. Use the information on this site at your own risk.

Copyright

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.

© Copyright 2009, Christian Fredh.