// remember that there is no is no rollback functionality for the table storage service right now // be cautious when using this function // if a role does not exist, we stop deleting roles, if a user in a role does not exist, we continue deleting // in case of error conditions, the behavior of this function is different than the SQL role provider public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) { SecUtility.CheckArrayParameter(ref roleNames, true, true, true, MaxTableRoleNameLength, "roleNames"); SecUtility.CheckArrayParameter(ref usernames, true, true, true, Constants.MaxTableUsernameLength, "usernames"); try { TableServiceContext svc = CreateDataServiceContext(); foreach (string role in roleNames) { if (!RoleExists(role)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", role)); } foreach (string user in usernames) { RoleRow row = GetUserInRole(svc, role, user); if (row == null) { Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} does not exist in the role {1}.", user, role)); continue; } try { svc.DeleteObject(row); svc.SaveChangesWithRetries(); } catch (Exception e) { var dsce = e.InnerException as DataServiceClientException; if (dsce != null && (dsce.StatusCode == (int)HttpStatusCode.NoContent || dsce.StatusCode == (int)HttpStatusCode.NotFound)) { Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} does not exist in the role {1}.", user, role)); svc.Detach(row); } else { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Error deleting user {0} from role {1}.", user, role)); } } } } } 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. public override void AddUsersToRoles(string[] usernames, string[] roleNames) { SecUtility.CheckArrayParameter(ref roleNames, true, true, true, MaxTableRoleNameLength, "roleNames"); SecUtility.CheckArrayParameter(ref usernames, true, true, true, Constants.MaxTableUsernameLength, "usernames"); RoleRow row; try { TableStorageDataServiceContext svc = CreateDataServiceContext(); foreach (string role in roleNames) { if (!RoleExists(role)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "The role {0} does not exist!", role)); } foreach (string user in usernames) { row = new RoleRow(_applicationName, role, user); try { svc.AddObject(_tableName, row); svc.SaveChangesWithRetries(); } catch (InvalidOperationException e) { HttpStatusCode status; if (TableStorageHelpers.EvaluateException(e, out status) && status == HttpStatusCode.Conflict) { // this element already exists or was created in a failed retry // this is not a fatal error; continue adding elements Log.Write(EventKind.Warning, string.Format(CultureInfo.InstalledUICulture, "The user {0} already exists in the role {1}.", user, role)); svc.Detach(row); } else { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Error adding user {0} to role {1}", user, role)); } } } } } catch (InvalidOperationException e) { throw new ProviderException("Error while accessing the data store.", e); } }
private static bool IsStaleRole(List <RoleRow> l, out RoleRow role) { role = null; if (l == null || l.Count == 0) { return(false); } string rolename = l.ElementAt(0).RoleName; foreach (RoleRow row in l) { Debug.Assert(row.RoleName == rolename); if (string.IsNullOrEmpty(row.UserName)) { role = row; return(false); } } return(true); }
public override void CreateRole(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableServiceContext svc = CreateDataServiceContext(); RoleRow newRole = new RoleRow(_applicationName, roleName, string.Empty); svc.AddObject(_tableName, newRole); svc.SaveChangesWithRetries(); } catch (InvalidOperationException e) { // when retry policies are used we cannot distinguish between a conflict and success // so, in the case of a conflict, we just retrun success here if (e.InnerException is DataServiceClientException && (e.InnerException as DataServiceClientException).StatusCode == (int)HttpStatusCode.Conflict) { return; // the role already exists } throw new ProviderException("Error accessing role table.", e); } }
private static bool IsStaleRole(List<RoleRow> l, out RoleRow role) { role = null; if (l == null || l.Count == 0) { return false; } string rolename = l.ElementAt(0).RoleName; foreach (RoleRow row in l) { Debug.Assert(row.RoleName == rolename); if (string.IsNullOrEmpty(row.UserName)) { role = row; return false; } } return true; }
public override void CreateRole(string roleName) { SecUtility.CheckParameter(ref roleName, true, true, true, MaxTableRoleNameLength, "rolename"); try { TableStorageDataServiceContext svc = CreateDataServiceContext(); RoleRow newRole = new RoleRow(_applicationName, roleName, string.Empty); svc.AddObject(_tableName, newRole); svc.SaveChangesWithRetries(); } catch (InvalidOperationException e) { HttpStatusCode status; // when retry policies are used we cannot distinguish between a conflict and success // so, in the case of a conflict, we just retrun success here if (TableStorageHelpers.EvaluateException(e, out status) && status == HttpStatusCode.Conflict) { return; // the role already exists } throw new ProviderException("Error accessing role table.", e); } }
// RoleProvider methods public override void Initialize(string name, NameValueCollection config) { // Verify that config isn't null if (config == null) { throw new ArgumentNullException("config"); } // Assign the provider a default name if it doesn't have one if (String.IsNullOrEmpty(name)) { name = "TableStorageRoleProvider"; } // Add a default "description" attribute to config if the // attribute doesn't exist or is empty if (string.IsNullOrEmpty(config["description"])) { config.Remove("description"); config.Add("description", "Table storage-based role provider"); } // Call the base class's Initialize method base.Initialize(name, config); bool allowInsecureRemoteEndpoints = Configuration.GetBooleanValue(config, "allowInsecureRemoteEndpoints", false); // structure storage-related properties ApplicationName = Configuration.GetStringValueWithGlobalDefault(config, "applicationName", Configuration.DefaultProviderApplicationNameConfigurationString, Configuration.DefaultProviderApplicationName, false); _accountName = Configuration.GetStringValue(config, "accountName", null, true); _sharedKey = Configuration.GetStringValue(config, "sharedKey", null, true); _tableName = Configuration.GetStringValueWithGlobalDefault(config, "roleTableName", Configuration.DefaultRoleTableNameConfigurationString, Configuration.DefaultRoleTableName, false); _membershipTableName = Configuration.GetStringValueWithGlobalDefault(config, "membershipTableName", Configuration.DefaultMembershipTableNameConfigurationString, Configuration.DefaultMembershipTableName, false); _tableServiceBaseUri = Configuration.GetStringValue(config, "tableServiceBaseUri", null, true); // remove required attributes config.Remove("allowInsecureRemoteEndpoints"); config.Remove("applicationName"); config.Remove("accountName"); config.Remove("sharedKey"); config.Remove("roleTableName"); config.Remove("membershipTableName"); config.Remove("tableServiceBaseUri"); // Throw an exception if unrecognized attributes remain if (config.Count > 0) { string attr = config.GetKey(0); if (!String.IsNullOrEmpty(attr)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Unrecognized attribute: {0}", attr)); } } //StorageCredentialsAccountAndKey info = null; string baseUri = null; try { var sharedKey = Configuration.TryGetAppSetting(Configuration.DefaultAccountSharedKeyConfigurationString); var accountName = Configuration.TryGetAppSetting(Configuration.DefaultAccountNameConfigurationString); baseUri = Configuration.TryGetAppSetting(Configuration.DefaultTableStorageEndpointConfigurationString); if (_tableServiceBaseUri != null) { baseUri = _tableServiceBaseUri; } if (_accountName != null) { accountName = _accountName; } if (_sharedKey != null) { sharedKey = _sharedKey; } if (String.IsNullOrEmpty(sharedKey) || String.IsNullOrEmpty(accountName) || String.IsNullOrEmpty(baseUri)) { throw new ConfigurationErrorsException("Account information incomplete!"); } //info = new StorageCredentialsAccountAndKey(accountName, sharedKey); //SecUtility.CheckAllowInsecureEndpoints(allowInsecureRemoteEndpoints, info, new Uri(baseUri)); _tableStorage = new sqlTableClient(baseUri);//, info); //_tableStorage.RetryPolicy = _tableRetry; if (_tableStorage.CreateTableIfNotExist(_tableName)) { var ctx = _tableStorage.GetDataServiceContext(); var dummyRow = new RoleRow("dummy", "fake", "none"); ctx.AddObject(_tableName, dummyRow); ctx.SaveChangesWithRetries(); ctx.DeleteObject(dummyRow); ctx.SaveChangesWithRetries(); } } catch (SecurityException) { throw; } // catch InvalidOperationException as well as StorageException catch (Exception e) { //string exceptionDescription = Configuration.GetInitExceptionDescription(info, new Uri(baseUri), "table storage configuration"); string exceptionDescription = Configuration.GetInitExceptionDescription(new Uri(baseUri), "table storage configuration"); string tableName = (_tableName == null) ? "no role table name specified" : _tableName; Log.Write(EventKind.Error, "Could not create or find role table: " + tableName + "!" + Environment.NewLine + exceptionDescription + Environment.NewLine + e.Message + Environment.NewLine + e.StackTrace); throw new ProviderException("Could not create or find role table. The most probable reason for this is that " + "the storage endpoints are not configured correctly. Please look at the configuration settings " + "in your .cscfg and Web.config files. More information about this error " + "can be found in the logs when running inside the hosting environment or in the output " + "window of Visual Studio.", e); } }
// RoleProvider methods public override void Initialize(string name, NameValueCollection config) { // Verify that config isn't null if (config == null) { throw new ArgumentNullException("config"); } // Assign the provider a default name if it doesn't have one if (String.IsNullOrEmpty(name)) { name = "TableStorageRoleProvider"; } // Add a default "description" attribute to config if the // attribute doesn't exist or is empty if (string.IsNullOrEmpty(config["description"])) { config.Remove("description"); config.Add("description", "Table storage-based role provider"); } // Call the base class's Initialize method base.Initialize(name, config); bool allowInsecureRemoteEndpoints = Configuration.GetBooleanValue(config, "allowInsecureRemoteEndpoints", false); // structure storage-related properties ApplicationName = Configuration.GetStringValueWithGlobalDefault(config, "applicationName", Configuration.DefaultProviderApplicationNameConfigurationString, Configuration.DefaultProviderApplicationName, false); _accountName = Configuration.GetStringValue(config, "accountName", null, true); _sharedKey = Configuration.GetStringValue(config, "sharedKey", null, true); _tableName = Configuration.GetStringValueWithGlobalDefault(config, "roleTableName", Configuration.DefaultRoleTableNameConfigurationString, Configuration.DefaultRoleTableName, false); _membershipTableName = Configuration.GetStringValueWithGlobalDefault(config, "membershipTableName", Configuration.DefaultMembershipTableNameConfigurationString, Configuration.DefaultMembershipTableName, false); _tableServiceBaseUri = Configuration.GetStringValue(config, "tableServiceBaseUri", null, true); // remove required attributes config.Remove("allowInsecureRemoteEndpoints"); config.Remove("applicationName"); config.Remove("accountName"); config.Remove("sharedKey"); config.Remove("roleTableName"); config.Remove("membershipTableName"); config.Remove("tableServiceBaseUri"); // Throw an exception if unrecognized attributes remain if (config.Count > 0) { string attr = config.GetKey(0); if (!String.IsNullOrEmpty(attr)) { throw new ProviderException(string.Format(CultureInfo.InstalledUICulture, "Unrecognized attribute: {0}", attr)); } } StorageCredentialsAccountAndKey info = null; string baseUri = null; try { var sharedKey = Configuration.TryGetAppSetting(Configuration.DefaultAccountSharedKeyConfigurationString); var accountName = Configuration.TryGetAppSetting(Configuration.DefaultAccountNameConfigurationString); baseUri = Configuration.TryGetAppSetting(Configuration.DefaultTableStorageEndpointConfigurationString); if (_tableServiceBaseUri != null) { baseUri = _tableServiceBaseUri; } if (_accountName != null) { accountName = _accountName; } if (_sharedKey != null) { sharedKey = _sharedKey; } if (String.IsNullOrEmpty(sharedKey) || String.IsNullOrEmpty(accountName) || String.IsNullOrEmpty(baseUri)) throw new ConfigurationErrorsException("Account information incomplete!"); info = new StorageCredentialsAccountAndKey(accountName, sharedKey); SecUtility.CheckAllowInsecureEndpoints(allowInsecureRemoteEndpoints, info, new Uri(baseUri)); _tableStorage = new CloudTableClient(baseUri, info); _tableStorage.RetryPolicy = _tableRetry; if (_tableStorage.CreateTableIfNotExist(_tableName)) { var ctx = _tableStorage.GetDataServiceContext(); var dummyRow = new RoleRow("dummy", "fake", "none"); ctx.AddObject(_tableName, dummyRow); ctx.SaveChangesWithRetries(); ctx.DeleteObject(dummyRow); ctx.SaveChangesWithRetries(); } } catch (SecurityException) { throw; } // catch InvalidOperationException as well as StorageException catch (Exception e) { string exceptionDescription = Configuration.GetInitExceptionDescription(info, new Uri(baseUri), "table storage configuration"); string tableName = (_tableName == null) ? "no role table name specified" : _tableName; Log.Write(EventKind.Error, "Could not create or find role table: " + tableName + "!" + Environment.NewLine + exceptionDescription + Environment.NewLine + e.Message + Environment.NewLine + e.StackTrace); throw new ProviderException("Could not create or find role table. The most probable reason for this is that " + "the storage endpoints are not configured correctly. Please look at the configuration settings " + "in your .cscfg and Web.config files. More information about this error " + "can be found in the logs when running inside the hosting environment or in the output " + "window of Visual Studio.", e); } }