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); } }
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); } }