private SessionRow GetSession(string id, DataServiceContext context) { Debug.Assert(context != null); Debug.Assert(id != null && id.Length <= TableStorageConstants.MaxStringPropertySizeInChars); try { DataServiceQuery <SessionRow> queryObj = context.CreateQuery <SessionRow>(_tableName); IEnumerable <SessionRow> query = from session in queryObj where session.PartitionKey == SecUtility.CombineToKey(_applicationName, id) select session; TableStorageDataServiceQuery <SessionRow> q = new TableStorageDataServiceQuery <SessionRow>(query as DataServiceQuery <SessionRow>, _tableRetry); IEnumerable <SessionRow> sessions = q.ExecuteWithRetries(); // enumerate the result and store it in a list List <SessionRow> sessionList = new List <SessionRow>(sessions); if (sessionList != null && sessionList.Count() == 1) { return(sessionList.First()); } else if (sessionList != null && sessionList.Count() > 1) { throw new ProviderException("Multiple sessions with the same name!"); } else { return(null); } } catch (Exception e) { throw new ProviderException("Error accessing storage.", e); } }
private static void DeleteAllEntriesFromSampleTable(TableStorageDataServiceContext svc, string tableName) { IEnumerable <SampleEntity> res; TableStorageDataServiceQuery <SampleEntity> q; Console.WriteLine("Deleting all entities from the table..."); Console.WriteLine("This can take a while..."); var qResult = from c in svc.CreateQuery <SampleEntity>(tableName) select c; q = new TableStorageDataServiceQuery <SampleEntity>(qResult as DataServiceQuery <SampleEntity>); res = q.ExecuteAllWithRetries(); int i = 0; foreach (SampleEntity s in res) { svc.DeleteObject(s); svc.SaveChangesWithRetries(); if (++i % 50 == 0) { Console.WriteLine("Deleted element " + i); } } }
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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <RoleRow> 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; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteWithRetries(); if (userRows == null) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist.", roleName)); } List <RoleRow> 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); } }
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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <RoleRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) || user.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) select user; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); 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[] GetUsersInRole(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <RoleRow> query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) >= 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.RowKey == SecUtility.Escape(roleName) select user; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { // role does not exist; we are supposed to throw an exception here throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", roleName)); } List <RoleRow> l = new List <RoleRow>(userRows); if (l.Count == 0 || IsStaleRole(l, roleName)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", roleName)); } List <string> ret = new List <string>(); foreach (RoleRow user in l) { if (!string.IsNullOrEmpty(user.UserName)) { ret.Add(user.UserName); } } return(ret.ToArray()); } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
public override bool RoleExists(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <RoleRow> query = from role in queryObj where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) && role.RowKey == SecUtility.Escape(roleName) select role; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); try { // this query addresses exactly one result // we thus should get an exception if there is no element q.ExecuteWithRetries(); return(true); } catch (DataServiceQueryException e) { HttpStatusCode s; if (TableStorageHelpers.EvaluateException(e, out s) && s == HttpStatusCode.NotFound) { return(false); } else { throw; } } } 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); IEnumerable <RoleRow> query = from role in queryObj where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) select role; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); 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); } }
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); IEnumerable <RoleRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) && user.RowKey == SecUtility.Escape(rolename) select user; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); try { IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); return(userRows.First()); } catch (DataServiceQueryException e) { HttpStatusCode s; if (TableStorageHelpers.EvaluateException(e, out s) && s == HttpStatusCode.NotFound) { return(null); } else { throw; } } } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<RoleRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) || user.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) select user; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); 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); IEnumerable<RoleRow> query = from role in queryObj where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) select role; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); 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); } }
// 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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<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; } 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; } 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; } TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { throw new ProviderException("The role does not exist!"); } List<RoleRow> 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!"); } List<string> 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); } }
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<RoleRow> 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; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { return false; } List<RoleRow> l = new List<RoleRow>(userRows); if (l.Count == 0) { // the role does not exist return false; } RoleRow role; if (IsStaleRole(l, out role)) { return false; } if (l.Count > 1 && throwOnPopulatedRole) { throw new ProviderException("Cannot delete populated role."); } svc.DeleteObject(role); svc.SaveChangesWithRetries(); // lets try to remove all remaining elements in the role foreach(RoleRow row in l) { if (row != role) { try { svc.DeleteObject(row); svc.SaveChangesWithRetries(); } catch (InvalidOperationException ex) { HttpStatusCode status; if (TableStorageHelpers.EvaluateException(ex, out status) && (status == HttpStatusCode.NoContent || status == HttpStatusCode.NotFound)) { // this element already was already deleted by another process or during a failed retry // this is not a fatal error; continue deleting elements Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} does not exist in the role {1}.", row.UserName, row.RoleName)); } else { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Error deleting user {0} from role {1}.", row.UserName, row.RoleName)); } } } } return true; } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
private SessionRow GetSession(string id, DataServiceContext context) { Debug.Assert(context != null); Debug.Assert(id != null && id.Length <= TableStorageConstants.MaxStringPropertySizeInChars); try { DataServiceQuery<SessionRow> queryObj = context.CreateQuery<SessionRow>(_tableName); IEnumerable<SessionRow> query = from session in queryObj where session.PartitionKey == SecUtility.CombineToKey(_applicationName, id) select session; TableStorageDataServiceQuery<SessionRow> q = new TableStorageDataServiceQuery<SessionRow>(query as DataServiceQuery<SessionRow>, _tableRetry); IEnumerable<SessionRow> sessions = q.ExecuteWithRetries(); // enumerate the result and store it in a list List<SessionRow> sessionList = new List<SessionRow>(sessions); if (sessionList != null && sessionList.Count() == 1) { return sessionList.First(); } else if (sessionList != null && sessionList.Count() > 1) { throw new ProviderException("Multiple sessions with the same name!"); } else { return null; } } catch (Exception e) { throw new ProviderException("Error accessing storage.", e); } }
// this method shows an alternative way of accessing/creating DataServiceContext objects // this approach is closer to what tools generate for normal ADO.NET Data Services projects internal static void RunSamples1() { StorageAccountInfo account = null; try { Console.WriteLine("Show how to create tables and queries using the SampleDataServiceContext class..."); account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration(); SampleDataServiceContext svc = new SampleDataServiceContext(account); svc.RetryPolicy = RetryPolicies.RetryN(3, TimeSpan.FromSeconds(1)); // Create 'SampleTable' // this uses the SampleDataServiceContext class TableStorage.CreateTablesFromModel(typeof(SampleDataServiceContext), account); string sampleTableName = SampleDataServiceContext.SampleTableName; DeleteAllEntriesFromSampleTable(svc, sampleTableName); svc.AddObject(SampleDataServiceContext.SampleTableName, new SampleEntity("sample", "entity")); svc.SaveChangesWithRetries(); var qResult = from c in svc.SampleTable where c.PartitionKey == "samplepartitionkey" && c.RowKey == "samplerowkey1" select c; TableStorageDataServiceQuery <SampleEntity> q = new TableStorageDataServiceQuery <SampleEntity>(qResult as DataServiceQuery <SampleEntity>, svc.RetryPolicy); try { // the query references the whole key and explicitly addresses one entity // thus, this query can generate an exception if there are 0 results during enumeration IEnumerable <SampleEntity> res = q.ExecuteAllWithRetries(); foreach (SampleEntity s in res) { Console.WriteLine("This code is not reached. " + s.PartitionKey); } } catch (DataServiceQueryException e) { HttpStatusCode s; if (TableStorageHelpers.EvaluateException(e, out s) && s == HttpStatusCode.NotFound) { // this would mean the entity was not found Console.WriteLine("The entity was not found. This is expected here."); } } Console.WriteLine("Delete all entries in the sample table."); DeleteAllEntriesFromSampleTable(svc, sampleTableName); Console.WriteLine("Table sample 1 finished!"); } catch (DataServiceRequestException dsre) { Console.WriteLine("DataServiceRequestException: " + GetExceptionMessage(dsre)); ShowTableStorageErrorMessage(account.BaseUri.ToString()); } catch (InvalidOperationException ioe) { Console.WriteLine("Storage service error: " + GetExceptionMessage(ioe)); ShowTableStorageErrorMessage(account.BaseUri.ToString()); } }
private void UpdateUser(string username, DateTime now) { SecUtility.CheckParameter(ref username, true, true, true, Constants.MaxTableUsernameLength, "username"); _providerRetry(() => { TableStorageDataServiceContext context = CreateDataServiceContext(); DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) select user; TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> users = q.ExecuteWithRetries(); if (users == null) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The user {0} does not exist!", username)); } List<MembershipRow> memberList = new List<MembershipRow>(users); if (memberList.Count > 1) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Multiple users under the same name {0}!", username)); } memberList.First().LastActivityDateUtc = now; context.UpdateObject(memberList.First()); context.SaveChangesWithRetries(); }); }
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <RoleRow> 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; TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { return(false); } List <RoleRow> l = new List <RoleRow>(userRows); if (l.Count == 0) { // the role does not exist return(false); } RoleRow role; if (IsStaleRole(l, out role)) { return(false); } if (l.Count > 1 && throwOnPopulatedRole) { throw new ProviderException("Cannot delete populated role."); } svc.DeleteObject(role); svc.SaveChangesWithRetries(); // lets try to remove all remaining elements in the role foreach (RoleRow row in l) { if (row != role) { try { svc.DeleteObject(row); svc.SaveChangesWithRetries(); } catch (InvalidOperationException ex) { HttpStatusCode status; if (TableStorageHelpers.EvaluateException(ex, out status) && (status == HttpStatusCode.NoContent || status == HttpStatusCode.NotFound)) { // this element already was already deleted by another process or during a failed retry // this is not a fatal error; continue deleting elements Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} does not exist in the role {1}.", row.UserName, row.RoleName)); } else { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Error deleting user {0} from role {1}.", row.UserName, row.RoleName)); } } } } return(true); } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
public override bool RoleExists(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<RoleRow> query = from role in queryObj where role.PartitionKey == SecUtility.CombineToKey(_applicationName, string.Empty) && role.RowKey == SecUtility.Escape(roleName) select role; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); try { // this query addresses exactly one result // we thus should get an exception if there is no element q.ExecuteWithRetries(); return true; } catch (DataServiceQueryException e) { HttpStatusCode s; if (TableStorageHelpers.EvaluateException(e, out s) && s == HttpStatusCode.NotFound) { return false; } else { throw; } } } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
private List<MembershipRow> GetUsersInactive(DataServiceContext context, string usernameToMatch, bool startswith, ProfileAuthenticationOption auth, DateTime userInactiveSinceDateUtc) { DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = null; // play a trick to deal with the restrictions of currently supported linq queries bool first, second; if (auth == ProfileAuthenticationOption.All) { first = true; second = false; } else if (auth == ProfileAuthenticationOption.Anonymous) { first = true; second = true; } else { first = false; second = false; } if (startswith && usernameToMatch == string.Empty) { query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty && (user.IsAnonymous == first || user.IsAnonymous == second) select user; } else if (startswith) { query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty && user.UserName.CompareTo(usernameToMatch) >= 0 && (user.IsAnonymous == first || user.IsAnonymous == second) select user; } else { query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.CombineToKey(_applicationName, usernameToMatch)) == 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty && (user.IsAnonymous == first || user.IsAnonymous == second) select user; } /* if (auth == ProfileAuthenticationOption.All) { query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty select user; } else if (auth == ProfileAuthenticationOption.Anonymous) { query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty && user.IsAnonymous == true select user; } else { Debug.Assert(auth == ProfileAuthenticationOption.Authenticated); query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.LastActivityDateUtc < userInactiveSinceDateUtc && user.ProfileBlobName != string.Empty && user.IsAnonymous == false select user; } */ TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> users = q.ExecuteAllWithRetries(); if (users == null) { return new List<MembershipRow>(); ; } return new List<MembershipRow>(users); }
public override int DeleteProfiles(string[] usernames) { SecUtility.CheckArrayParameter(ref usernames, true, true, true, Constants.MaxTableUsernameLength, "usernames"); TableStorageDataServiceContext context = CreateDataServiceContext(); MembershipRow currentProfile = null; int ret = 0; try { foreach (string name in usernames) { DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = from profile in queryObj where profile.PartitionKey == SecUtility.CombineToKey(_applicationName, name) select profile; TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> profiles = q.ExecuteAllWithRetries(); if (profiles == null) { continue; } // enumerate results List<MembershipRow> l = new List<MembershipRow>(profiles); if (l == null || l.Count == 0) { continue; } else if (l.Count > 1) { // there cannot be more than one items in the list (application name + user name is a primary key) Log.Write(EventKind.Warning, "There should only be one user with the same name in one application!"); } try { currentProfile = l.First(); if (currentProfile.ProfileIsCreatedByProfileProvider) { // we can completely delete this user from the table context.DeleteObject(currentProfile); context.SaveChangesWithRetries(); } else { currentProfile.ProfileBlobName = string.Empty; currentProfile.ProfileLastUpdatedUtc = TableStorageConstants.MinSupportedDateTime; currentProfile.ProfileSize = 0; context.UpdateObject(currentProfile); context.SaveChangesWithRetries(); } ret++; // if we fail after savechanges, the profile will still be deleted // but it will be a stale profile // deletes all blobs that start with the prefix _blobProvider.DeleteBlobsWithPrefix(GetProfileBlobPrefix(l.First().UserName)); } catch (InvalidOperationException) { // we ignore these errors and try to continue deleting Log.Write(EventKind.Warning, "The deletion of a single profile failed! Problem when writing to table storage."); if (currentProfile != null) { context.Detach(currentProfile); } } catch (StorageException) { // we ignore these errors and try to continue deleting Log.Write(EventKind.Warning, "The deletion of a single profile failed! Problem when deleting blob."); } } return ret; } // catch all exceptions, also InvalidOperationExceptions outside the above try block catch (Exception e) { throw new ProviderException("Error while accessing the data store.", e); } }
private void CreateOrUpdateUserAndProfile(string username, bool authenticated, DateTime now, string blobName, int size) { Debug.Assert(now.Kind == DateTimeKind.Utc); SecUtility.CheckParameter(ref username, true, true, true, Constants.MaxTableUsernameLength, "username"); _providerRetry(() => { TableStorageDataServiceContext context = CreateDataServiceContext(); DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) select user; TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> users = q.ExecuteWithRetries(); // instantiate results List<MembershipRow> userList = null; if (users != null) { userList = new List<MembershipRow>(users); } if (userList != null && userList.Count > 0) { MembershipRow current = userList.First(); if (current.IsAnonymous != !authenticated) { // this is an error because we would need to create a user with the same name // this should not happen throw new ProviderException("A user with the same name but with a different authentication status already exists!"); } current.LastActivityDateUtc = now; current.ProfileBlobName = blobName; current.ProfileSize = size; current.ProfileLastUpdatedUtc = now; context.UpdateObject(current); } else { if (authenticated) { Log.Write(EventKind.Warning, "The authenticated user does not exist in the database."); } MembershipRow member = new MembershipRow(_applicationName, username); member.LastActivityDateUtc = now; member.IsAnonymous = !authenticated; member.ProfileBlobName = blobName; member.ProfileSize = size; member.ProfileLastUpdatedUtc = now; member.ProfileIsCreatedByProfileProvider = true; context.AddObject(_tableName, member); } context.SaveChanges(); }); }
// we don't use _providerRetry here because of the out parameter prof private bool DoesProfileExistAndUpdateUser(string username, out MembershipRow prof) { SecUtility.CheckParameter(ref username, true, true, true, Constants.MaxTableUsernameLength, "username"); int curRetry = 0; bool retry = false; do { retry = false; try { TableStorageDataServiceContext context = CreateDataServiceContext(); DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = from profile in queryObj where profile.PartitionKey == SecUtility.CombineToKey(_applicationName, username) select profile; TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> profiles = q.ExecuteWithRetries(); if (profiles == null) { prof = null; return false; } // instantiate results List<MembershipRow> profileList = new List<MembershipRow>(profiles); if (profileList.Count > 1) { throw new ProviderException("Multiple profile rows for the same user!"); } if (profileList.Count == 1) { prof = profileList.First(); if (!string.IsNullOrEmpty(prof.ProfileBlobName)) { prof.LastActivityDateUtc = DateTime.UtcNow; context.UpdateObject(prof); context.SaveChangesWithRetries(); return true; } else { return false; } } else { prof = null; return false; } } catch (InvalidOperationException e) { HttpStatusCode status; if (TableStorageHelpers.EvaluateException(e, out status) && status == HttpStatusCode.PreconditionFailed) { retry = true; } else { throw new ProviderException("Error accessing storage.", e); } } } while (curRetry++ < NumRetries && retry); prof = null; return false; }
public override string[] GetUsersInRole(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<RoleRow> query = from user in queryObj where user.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) >= 0 && user.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 && user.RowKey == SecUtility.Escape(roleName) select user; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { // role does not exist; we are supposed to throw an exception here throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", roleName)); } List<RoleRow> l = new List<RoleRow>(userRows); if (l.Count == 0 || IsStaleRole(l, roleName)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", roleName)); } List<string> ret = new List<string>(); foreach (RoleRow user in l) { if (!string.IsNullOrEmpty(user.UserName)) { ret.Add(user.UserName); } } return ret.ToArray(); } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
// 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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery <RoleRow> queryObj = svc.CreateQuery <RoleRow>(_tableName); IEnumerable <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; } 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; } 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; } TableStorageDataServiceQuery <RoleRow> q = new TableStorageDataServiceQuery <RoleRow>(query as DataServiceQuery <RoleRow>, _tableRetry); IEnumerable <RoleRow> userRows = q.ExecuteAllWithRetries(); if (userRows == null) { throw new ProviderException("The role does not exist!"); } List <RoleRow> 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!"); } List <string> 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); } }
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 { TableStorageDataServiceContext svc = CreateDataServiceContext(); DataServiceQuery<RoleRow> queryObj = svc.CreateQuery<RoleRow>(_tableName); IEnumerable<RoleRow> 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; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); IEnumerable<RoleRow> userRows = q.ExecuteWithRetries(); if (userRows == null) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist.", roleName)); } List<RoleRow> 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); } }
// shows alternative ways of generating DataServiceContext objects internal static void RunSamples2() { StorageAccountInfo account = null; try { account = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration(); TableStorage tableStorage = TableStorage.Create(account); tableStorage.RetryPolicy = RetryPolicies.RetryN(3, TimeSpan.FromSeconds(1)); // the DataServiceContext object inherits its retry policy from tableStorage in this case TableStorageDataServiceContext svc = tableStorage.GetDataServiceContext(); Console.WriteLine("Table creation, delete and list samples..."); string sampleTableName = SampleDataServiceContext.SampleTableName; tableStorage.TryCreateTable(sampleTableName); DeleteAllEntriesFromSampleTable(svc, sampleTableName); Console.WriteLine("List all tables in the account."); IEnumerable <string> tables2 = tableStorage.ListTables(); foreach (string n1 in tables2) { Console.WriteLine(n1); } Console.WriteLine("Inserting entities into the table..."); SampleEntity t = new SampleEntity("samplepartitionkey", "samplerowkey"); svc.AddObject(sampleTableName, t); svc.SaveChangesWithRetries(); //Detach the existing entity so that we can demonstrate the server side //error when you try to insert an same object with the same keys svc.Detach(t); // Insert an entity with the same keys Console.WriteLine("Try to insert the same entity into the table and show how to deal with error conditions."); t = new SampleEntity("samplepartitionkey", "samplerowkey"); svc.AddObject(sampleTableName, t); try { svc.SaveChangesWithRetries(); // getting here is an error because inserting the same row twice raises an exception Console.WriteLine("Should not get here. Succeeded inserting two entities with the same keys"); } catch (Exception e) { HttpStatusCode status; StorageExtendedErrorInformation errorInfo; if (TableStorageHelpers.EvaluateException(e, out status, out errorInfo) && status == HttpStatusCode.Conflict) { // the row has already been inserted before, this is expected here if (errorInfo != null) { Console.WriteLine("Attempting to insert row with same keys resulted in error {0} : {1}", errorInfo.ErrorCode, errorInfo.ErrorMessage); } } else { throw; } } svc.Detach(t); Console.WriteLine("Insert a large item into the table."); t = new SampleEntity("samplepartitionkey", "samplerowkey1"); t.B = new String('a', 1000); svc.AddObject(sampleTableName, t); svc.SaveChangesWithRetries(); Console.WriteLine("Create a normal DataServiceContext object (not TableStorageDataServiceContext) and attach it to a TableStorage object."); DataServiceContext svc2 = new DataServiceContext( TableStorage.GetServiceBaseUri(account.BaseUri, account.UsePathStyleUris, account.AccountName)); tableStorage.Attach(svc2); var qResult = from c in svc2.CreateQuery <SampleEntity>(sampleTableName) where c.RowKey == "samplerowkey1" select c; foreach (SampleEntity cust in qResult) { if (cust.B != t.B) { Console.WriteLine("Sample failed. Did not read the entity property just written"); } } Console.WriteLine("Insert many rows in a table and show the API for dealing with query result pagination."); int num = 2100; Console.WriteLine("Inserting {0} rows.", num.ToString(CultureInfo.CurrentUICulture)); for (int i = 0; i < num; i++) { t = new SampleEntity("samplestring", i.ToString(CultureInfo.InvariantCulture)); svc.AddObject(sampleTableName, t); svc.SaveChangesWithRetries(); if ((i + 1) % 50 == 0) { Console.WriteLine("Inserted row {0}.", (i + 1).ToString(CultureInfo.CurrentUICulture)); } } Console.WriteLine("Executing query that will return many results. This can take a while..."); var qResult2 = from c in svc.CreateQuery <SampleEntity>(sampleTableName) where c.PartitionKey == "samplestring" select c; TableStorageDataServiceQuery <SampleEntity> tableStorageQuery = new TableStorageDataServiceQuery <SampleEntity>(qResult2 as DataServiceQuery <SampleEntity>); IEnumerable <SampleEntity> res = tableStorageQuery.ExecuteAllWithRetries(); Console.WriteLine("Retrieved query results:"); foreach (SampleEntity entity in res) { Console.WriteLine("Partition key: {0}, row key: {1}.", entity.PartitionKey, entity.RowKey); } Console.WriteLine("Delete all entries in the sample table."); DeleteAllEntriesFromSampleTable(tableStorage.GetDataServiceContext(), sampleTableName); tableStorage.DeleteTable(sampleTableName); Console.WriteLine("Table samples finished!"); } catch (DataServiceRequestException dsre) { Console.WriteLine("DataServiceRequestException: " + GetExceptionMessage(dsre)); ShowTableStorageErrorMessage(account.BaseUri.ToString()); } catch (InvalidOperationException ioe) { Console.WriteLine("Storage service error: " + GetExceptionMessage(ioe)); ShowTableStorageErrorMessage(account.BaseUri.ToString()); } }
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); IEnumerable<RoleRow> query = from user in queryObj where user.PartitionKey == SecUtility.CombineToKey(_applicationName, username) && user.RowKey == SecUtility.Escape(rolename) select user; TableStorageDataServiceQuery<RoleRow> q = new TableStorageDataServiceQuery<RoleRow>(query as DataServiceQuery<RoleRow>, _tableRetry); try { IEnumerable<RoleRow> userRows = q.ExecuteAllWithRetries(); return userRows.First(); } catch (DataServiceQueryException e) { HttpStatusCode s; if (TableStorageHelpers.EvaluateException(e, out s) && s == HttpStatusCode.NotFound) { return null; } else { throw; } } } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
private List<MembershipRow> GetAllProfiles() { TableStorageDataServiceContext context = CreateDataServiceContext(); DataServiceQuery<MembershipRow> queryObj = context.CreateQuery<MembershipRow>(_tableName); IEnumerable<MembershipRow> query = from profile in queryObj where profile.PartitionKey.CompareTo(SecUtility.EscapedFirst(_applicationName)) > 0 && profile.PartitionKey.CompareTo(SecUtility.NextComparisonString(SecUtility.EscapedFirst(_applicationName))) < 0 select profile; TableStorageDataServiceQuery<MembershipRow> q = new TableStorageDataServiceQuery<MembershipRow>(query as DataServiceQuery<MembershipRow>, _tableRetry); IEnumerable<MembershipRow> profiles = q.ExecuteAllWithRetries(); if (profiles == null) { return new List<MembershipRow>(); ; } return new List<MembershipRow>(profiles); }