public async Task DeleteIdentity(Guid identityId, CancellationToken cancellationToken = default(CancellationToken)) { // Retrieve identity entity var retrieveOperation = TableOperation.Retrieve <AzureIdentityEntity>(Constants.PartitionNames.IdentityPrimary, identityId.ToString()); var retrievedResult = await this.IdentityTable.ExecuteAsync(retrieveOperation, null, null, cancellationToken).ConfigureAwait(false); var retrievedEntity = (AzureIdentityEntity)retrievedResult?.Result; // Delete both foreign key as well as identity record var deleteIdentityEntity = new AzureIdentityEntity { PartitionKey = Constants.PartitionNames.IdentityPrimary, RowKey = identityId.ToString(), ETag = "*" }; var deleteForeignKeyEntity = new AzureIdentityForeignKeyEntity { PartitionKey = Constants.PartitionNames.EmailAddressToIdentityForeignKey, RowKey = retrievedEntity.EmailAddress, ETag = "*" }; // Delete all authentication tokens associated with the Identity var query = new TableQuery <AzureTokenEntity>(); query.Where(TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, Constants.PartitionNames.TokenPrimary), TableOperators.And, TableQuery.GenerateFilterConditionForGuid("IdentityId", QueryComparisons.Equal, identityId) ) ); TableContinuationToken continuationToken = null; do { var segmentResult = await this.TokenTable.ExecuteQuerySegmentedAsync(query, continuationToken, null, null, cancellationToken); var batchOption = new TableBatchOperation(); foreach (var entity in segmentResult.Results) { batchOption.Delete(entity); } if (batchOption.Count > 0) { await this.TokenTable.ExecuteBatchAsync(batchOption, null, null, cancellationToken).ConfigureAwait(false); } continuationToken = segmentResult.ContinuationToken; } while (continuationToken != null); // Delete identity and identity foreign key var deleteEntityOperation = TableOperation.Delete(deleteIdentityEntity); var deleteForeignKeyOperation = TableOperation.Delete(deleteForeignKeyEntity); var entityDeleteResult = await this.IdentityTable.ExecuteAsync(deleteEntityOperation, null, null, cancellationToken).ConfigureAwait(false); var foreignKeyDeleteResult = await this.IdentityTable.ExecuteAsync(deleteForeignKeyOperation, null, null, cancellationToken).ConfigureAwait(false); }
public async Task <CreateIdentityResult> CreateIdentity(string emailAddress, string password, CancellationToken cancellationToken = default(CancellationToken)) { try { emailAddress = emailAddress?.ToLowerInvariant(); var identityExistsCheck = await CheckIdentityExists(emailAddress, cancellationToken).ConfigureAwait(false); if (identityExistsCheck) { return(new CreateIdentityResult { Success = false }); } // Identity generation var perUserSalt = Security.GeneratePerUserSalt(); var hashedPassword = Security.GeneratePasswordHash(password, perUserSalt); var identityEntity = new AzureIdentityEntity() { IdentityId = Guid.NewGuid(), EmailAddress = emailAddress, PerUserSalt = perUserSalt, HashedPassword = hashedPassword }; var createIdentityOperation = TableOperation.Insert(identityEntity); // Identity foreign key generation var foreignKey = new AzureIdentityForeignKeyEntity { IdentityId = identityEntity.IdentityId, EmailAddress = emailAddress, }; var createForeignKeyOperation = TableOperation.Insert(foreignKey); // Insert identity information await this.IdentityTable.ExecuteAsync(createForeignKeyOperation, null, null, cancellationToken).ConfigureAwait(false); // This insert first to ensure there isn't a key conflict await this.IdentityTable.ExecuteAsync(createIdentityOperation, null, null, cancellationToken).ConfigureAwait(false); // Create verification token if email provider is set up if (this.EmailProvider != null) { await this.EmailProvider.SendVerificationEmail(identityEntity.IdentityId, this.EmailProvider.VerificationEmailSubject, cancellationToken).ConfigureAwait(false); // Do not create token until identity is verified return(new CreateIdentityResult { Success = true, IdentityId = identityEntity.IdentityId }); } // Token generation var token = Security.GenerateToken(); var tokenEntity = new AzureTokenEntity { IdentityId = identityEntity.IdentityId, Token = token }; var createTokenOperation = TableOperation.Insert(tokenEntity); await this.TokenTable.ExecuteAsync(createTokenOperation, null, null, cancellationToken).ConfigureAwait(false); return(new CreateIdentityResult { Success = true, IdentityId = identityEntity.IdentityId, Token = tokenEntity.Token }); } catch (StorageException) { return(new CreateIdentityResult { Success = false }); } }