private RoleRow GetUserInRole(DataServiceContext svc, string rolename, string username)
        {
            SecUtility.CheckParameter(ref username, true, true, true, Constants.MaxTableUsernameLength, "username");
            SecUtility.CheckParameter(ref rolename, true, true, true, MaxTableRoleNameLength, "rolename");

            try
            {
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                var query = (from user in queryObj
                             where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) &&
                             user.RowKey == SecUtility.Escape(rolename)
                             select user).AsTableServiceQuery();
                try
                {
                    IEnumerable <RoleRow> userRows = query.Execute();
                    return(userRows.FirstOrDefault());
                }
                catch (InvalidOperationException e)
                {
                    if (e.InnerException is DataServiceClientException && (e.InnerException as DataServiceClientException).StatusCode == (int)HttpStatusCode.NotFound)
                    {
                        return(null);
                    }
                    throw;
                }
            }
            catch (Exception e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
Exemple #2
0
        private SessionRow GetSession(string id, DataServiceContext context)
        {
            try
            {
                DataServiceQuery <SessionRow> queryObj = context.CreateQuery <SessionRow>(tableName);
                var query = (from session in queryObj
                             where session.PartitionKey == SecUtility.CombineToKey(applicationName, id)
                             select session).AsTableServiceQuery();
                IEnumerable <SessionRow> sessions = query.Execute();

                // enumerate the result and store it in a list
                var sessionList = new List <SessionRow>(sessions);
                if (sessionList.Count() == 1)
                {
                    return(sessionList.First());
                }

                if (sessionList.Count() > 1)
                {
                    throw new ProviderException("Multiple sessions with the same name!");
                }

                return(null);
            }
            catch (Exception e)
            {
                throw new ProviderException("Error accessing storage.", e);
            }
        }
        public override bool RoleExists(string roleName)
        {
            SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename");
            try
            {
                TableServiceContext        svc      = CreateDataServiceContext();
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                var query = (from role in queryObj
                             where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) &&
                             role.RowKey == SecUtility.Escape(roleName)
                             select role).AsTableServiceQuery();

                try
                {
                    // this query addresses exactly one result
                    // we thus should get an exception if there is no element
                    return(query.Execute().Any());
                }
                catch (InvalidOperationException e)
                {
                    if ((e.InnerException is DataServiceClientException && (e.InnerException as DataServiceClientException).StatusCode == (int)HttpStatusCode.NotFound) ||
                        (e.InnerException.InnerException is DataServiceClientException &&
                         (e.InnerException.InnerException as DataServiceClientException).StatusCode == (int)HttpStatusCode.NotFound))
                    {
                        return(false);
                    }
                    throw;
                }
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
 // applicationName + userName is partitionKey
 // roleName is rowKey
 public RoleRow(string applicationName, string roleName, string userName)
     : base(SecUtility.CombineToKey(applicationName, userName), SecUtility.Escape(roleName))
 {
     SecUtility.CheckParameter(ref applicationName, true, true, true, Constants.MaxTableApplicationNameLength, "applicationName");
     SecUtility.CheckParameter(ref roleName, true, true, true, 512, "roleName");
     SecUtility.CheckParameter(ref userName, true, false, true, Constants.MaxTableUsernameLength, "userName");
     ApplicationName = applicationName;
     RoleName        = roleName;
     UserName        = userName;
 }
        public override bool IsUserInRole(string username, string roleName)
        {
            SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename");
            SecUtility.CheckParameter(ref username, true, false, true, Constants.MaxTableUsernameLength, "username");
            if (username.Length < 1)
            {
                return(false);
            }

            try
            {
                TableServiceContext        svc      = CreateDataServiceContext();
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                var query = (from user in queryObj
                             where (user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) ||
                                    user.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty)) &&
                             user.RowKey == SecUtility.Escape(roleName)
                             select user).AsTableServiceQuery();

                IEnumerable <RoleRow> userRows = query.Execute();

                if (userRows == null)
                {
                    throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist.", roleName));
                }
                var l = new List <RoleRow>(userRows);
                if (l.Count == 0)
                {
                    throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist.", roleName));
                }
                RoleRow row;
                if (IsStaleRole(l, out row))
                {
                    throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist.", roleName));
                }
                if (l.Count > 2)
                {
                    throw new ProviderException("User name appears twice in the same role!");
                }
                if (l.Count == 1)
                {
                    Debug.Assert(string.IsNullOrEmpty(l.ElementAt(0).UserName));
                    return(false);
                }
                return(true);
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
        // application name + session id is partitionKey
        public SessionRow(string sessionId, string applicationName)
            : base(SecUtility.CombineToKey(applicationName, sessionId), string.Empty)
        {
            SecUtility.CheckParameter(ref sessionId, true, true, true, ProviderConfiguration.MaxStringPropertySizeInChars, "sessionId");
            SecUtility.CheckParameter(ref applicationName, true, true, true, Constants.MaxTableApplicationNameLength, "applicationName");

            Id = sessionId;
            ApplicationName = applicationName;
            ExpiresUtc      = ProviderConfiguration.MinSupportedDateTime;
            LockDateUtc     = ProviderConfiguration.MinSupportedDateTime;
            CreatedUtc      = ProviderConfiguration.MinSupportedDateTime;
            Timeout         = 0;
            BlobName        = string.Empty;
        }
        // partition key is applicationName + userName
        // rowKey is empty
        public MembershipRow(string applicationName, string userName)
            : base(SecUtility.CombineToKey(applicationName, userName), string.Empty)
        {
            if (string.IsNullOrEmpty(applicationName))
            {
                throw new ProviderException("Partition key cannot be empty!");
            }
            ////if (string.IsNullOrEmpty(userName))
            ////{
            ////    throw new ProviderException("RowKey cannot be empty!");
            ////}

            // applicationName + userName is partitionKey
            // the reasoning behind this is that we want to strive for the best scalability possible
            // chosing applicationName as the partition key and userName as row key would not give us that because
            // it would mean that a site with millions of users had all users on a single partition
            // having the applicationName and userName inside the partition key is important for queries as queries
            // for users in a single application are the most frequent
            // these queries are faster because application name and user name are part of the key
            ////PartitionKey = SecUtility.CombineToKey(applicationName, userName);
            ////RowKey = string.Empty;

            ApplicationName = applicationName;
            UserName        = userName;

            Password         = string.Empty;
            PasswordSalt     = string.Empty;
            Email            = string.Empty;
            PasswordAnswer   = string.Empty;
            PasswordQuestion = string.Empty;
            Comment          = string.Empty;
            ProfileBlobName  = string.Empty;

            CreateDateUtc                             = ProviderConfiguration.MinSupportedDateTime;
            LastLoginDateUtc                          = ProviderConfiguration.MinSupportedDateTime;
            LastActivityDateUtc                       = ProviderConfiguration.MinSupportedDateTime;
            LastLockoutDateUtc                        = ProviderConfiguration.MinSupportedDateTime;
            LastPasswordChangedDateUtc                = ProviderConfiguration.MinSupportedDateTime;
            FailedPasswordAttemptWindowStartUtc       = ProviderConfiguration.MinSupportedDateTime;
            FailedPasswordAnswerAttemptWindowStartUtc = ProviderConfiguration.MinSupportedDateTime;
            ProfileLastUpdatedUtc                     = ProviderConfiguration.MinSupportedDateTime;

            ProfileIsCreatedByProfileProvider = false;
            ProfileSize = 0;
        }
        public override string[] GetRolesForUser(string username)
        {
            SecUtility.CheckParameter(ref username, true, false, true, Constants.MaxTableUsernameLength, "username");
            if (username.Length < 1)
            {
                return(new string[0]);
            }

            try
            {
                TableServiceContext        svc      = CreateDataServiceContext();
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                var query = (from user in queryObj
                             where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) ||
                             user.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty)
                             select user).AsTableServiceQuery();

                IEnumerable <RoleRow> userRows = query.Execute();

                if (userRows == null)
                {
                    return(new string[0]);
                }
                List <RoleRow> l = new List <RoleRow>(userRows);
                if (l.Count == 0)
                {
                    return(new string[0]);
                }
                List <string> ret = new List <string>();
                foreach (RoleRow user in l)
                {
                    if (!string.IsNullOrEmpty(user.UserName) && !IsStaleRole(l, user.RoleName))
                    {
                        ret.Add(user.RoleName);
                    }
                }
                return(ret.ToArray());
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
        public override string[] GetAllRoles()
        {
            try
            {
                DataServiceContext         svc      = CreateDataServiceContext();
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                var query = (from role in queryObj
                             where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty)
                             select role).AsTableServiceQuery();
                IEnumerable <RoleRow> userRows = query.Execute();

                if (userRows == null)
                {
                    return(new string[0]);
                }
                List <RoleRow> l = new List <RoleRow>(userRows);
                if (l.Count == 0)
                {
                    return(new string[0]);
                }
                List <string> ret = new List <string>();
                foreach (RoleRow role in l)
                {
                    Debug.Assert(role.UserName != null);
                    if (string.IsNullOrEmpty(role.UserName))
                    {
                        ret.Add(role.RoleName);
                    }
                }
                return(ret.ToArray());
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }
        // Because of limited transactional support in the table storage offering, this function gives limited guarantees
        // for inserting all users into all roles.
        // We do not recommend using this function because of missing transactional support.

        // the username to match can be in a format that varies between providers
        // for this implementation, a syntax similar to the one used in the SQL provider is applied
        // "user%" will return all users in a role that start with the string "user"
        // the % sign can only appear at the end of the usernameToMatch parameter
        // because the current version of the table storage service does not support StartsWith in LINQ queries,
        // calling this function can cause significant network trafic when '%' is used in the usernameToMach
        // parameter
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename");
            SecUtility.CheckParameter(ref usernameToMatch, true, true, false, Constants.MaxTableUsernameLength, "usernameToMatch");

            bool startswith = false;

            if (usernameToMatch.Contains('%'))
            {
                if (usernameToMatch.IndexOf('%') != usernameToMatch.Length - 1)
                {
                    throw new ArgumentException("The TableStorageRoleProvider only supports search strings that contain '%' as the last character!");
                }
                usernameToMatch = usernameToMatch.Substring(0, usernameToMatch.Length - 1);
                startswith      = true;
            }

            try
            {
                TableServiceContext        svc      = CreateDataServiceContext();
                DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName);

                CloudTableQuery <RoleRow> query;

                if (startswith && string.IsNullOrEmpty(usernameToMatch))
                {
                    // get all users in the role
                    query = (from userRole in queryObj
                             where userRole.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) >= 0 &&
                             userRole.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 &&
                             userRole.RowKey == SecUtility.Escape(roleName)
                             select userRole).AsTableServiceQuery();
                }
                else if (startswith)
                {
                    // get all users in the role that start with the specified string (we cannot restrict the query more because StartsWith is not supported)
                    // we cannot include the username to search for in the key, because the key might e escaped
                    query = (from userRole in queryObj
                             where userRole.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) >= 0 &&
                             userRole.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 &&
                             userRole.RowKey == SecUtility.Escape(roleName) &&
                             (userRole.UserName.CompareTo(usernameToMatch) >= 0 || userRole.UserName == string.Empty)
                             select userRole).AsTableServiceQuery();
                }
                else
                {
                    // get a specific user
                    query = (from userRole in queryObj
                             where (userRole.PartitionKey == SecUtility.CombineToKey(_applicationName, usernameToMatch) ||
                                    userRole.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty)) &&
                             userRole.RowKey == SecUtility.Escape(roleName)
                             select userRole).AsTableServiceQuery();
                }

                IEnumerable <RoleRow> userRows = query.Execute();

                if (userRows == null)
                {
                    throw new ProviderException("The role does not exist!");
                }
                var l = new List <RoleRow>(userRows);
                if (l.Count == 0)
                {
                    // the role does not exist
                    throw new ProviderException("The role does not exist!");
                }
                RoleRow role;
                if (IsStaleRole(l, out role))
                {
                    throw new ProviderException("The role does not exist!");
                }
                var ret = new List <string>();
                foreach (RoleRow row in l)
                {
                    if (row != role)
                    {
                        if (startswith && !string.IsNullOrEmpty(usernameToMatch) && !row.UserName.StartsWith(usernameToMatch, StringComparison.Ordinal))
                        {
                            continue;
                        }
                        ret.Add(row.UserName);
                    }
                }
                return(ret.ToArray());
            }
            catch (InvalidOperationException e)
            {
                throw new ProviderException("Error while accessing the data store.", e);
            }
        }