How to delete a Pool user in AWS Cognito and C#? - c#

I have used the aws-samples example named aws-cognito-dot-net-desktop-app in C# and Android:
aws-cognito-dot-net-desktop-app
It works very well and correctly registers the user in Cognito.
To register a user, do the following:
bool success = await helper.SignUpUser(etUserName.Text, etPasswordUser.Text, etEmailUser.Text, etPhoneUser.Text);
That way the user is created, but a code needs to be entered that is sent to the user's email. The code entry is as follows:
CognitoHelper cognitoHelper = new CognitoHelper();
return await cognitoHelper.VerifyAccessCode(userName, codeSentToMail);
and the user registers without problems, that is to say, it works correctly:
Now I want to delete any user created, for which I am creating a task as follows:
internal async Task<bool> DeleteUser(string username)
{
try
{
AmazonCognitoIdentityProviderClient provider =
new Amazon.CognitoIdentityProvider.AmazonCognitoIdentityProviderClient(new Amazon.Runtime.AnonymousAWSCredentials(), RegionEndpoint.USEast1);
DeleteUserPoolRequest request = new DeleteUserPoolRequest();
request.UserPoolId = username;
DeleteUserPoolResponse deleteUserPoolClientResponse = await provider.DeleteUserPoolAsync(request);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return false;
}
}
When executing DeleteUserPoolRequest, an exception is thrown indicating an error of type Amazon.Runtime.ErrorType.Unknown
Any idea what I'm doing wrong?
Any comments or suggestions are welcome.

public static async Task<bool> DeleteUserFromAws(string emailId)
{
try
{
AmazonCognitoIdentityProviderClient cognito =
new AmazonCognitoIdentityProviderClient(awsAccessKeyId, awsSecretAccessKey, Region1);
CognitoUserPool cognitoUserPool = new CognitoUserPool(poolId, appClienId, cognito);
AdminGetUserRequest adminGetUserRequest = new AdminGetUserRequest();
adminGetUserRequest.Username = emailId;
adminGetUserRequest.UserPoolId = poolId;
AdminGetUserResponse adminGetUserResponse = await cognito.AdminGetUserAsync(adminGetUserRequest);
var getUserNameByEmaliID = adminGetUserResponse.Username;
AmazonCognitoIdentityProviderClient provider =
new AmazonCognitoIdentityProviderClient(awsAccessKeyId, awsSecretAccessKey, Region1);
AdminDeleteUserRequest request = new AdminDeleteUserRequest();
CancellationToken cancellationToken = default;
request.Username = getUserNameByEmaliID;
request.UserPoolId = poolId;
await provider.AdminDeleteUserAsync(request,cancellationToken);
return true;
}
catch (Exception ex)
{
Logger.log(ex, (Int32)Category.Fatal, (Int32)Priority.High);
throw;
}
}

Related

catch sign in error when using identity UserManager.CheckPasswordSignInAsync()

I've got a user linked to Identity. It all works I can login and Register and all data is good.
Now I want to catch the error that is happening when Sign In fails. I get the messages in the console, but I would like to catch them to log them or return them or one of them.
The errors:
warn: Microsoft.AspNetCore.Identity.UserManager[0]
Invalid password for user.
warn: Microsoft.AspNetCore.Identity.SignInManager[2]
User failed to provide the correct password.
If you have any other tips they are of course very welcome.
public async Task<UserReplyDTO> LoginAsync(UserLoginDTO userLoginDTO)
{
var user = await _userRepo.GetUserByEmail(userLoginDTO.Email);
var result = await _signInManager.CheckPasswordSignInAsync(user, userLoginDTO.Password, false);
//var result = await _signInManager.PasswordSignInAsync(userLoginDTO.Email, userLoginDTO.Password, false, false);
if (result.Succeeded)
{
UserReplyDTO userReplyDTO = new UserReplyDTO() { Email = user.Email, Id = user.Id, UserName = user.UserName, Role = user.Role };
string token = _tokenService.GetToken(user);
userReplyDTO.Token = token;
return userReplyDTO;
}
else
{
throw new UserLoginException("Bad UserName or Password!");
}
}
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> Login(UserLoginDTO userLoginDto)
{
try
{
var user = await _authService.LoginAsync(userLoginDto);
return Ok(user);
}
catch (UserLoginException ex)
{
return BadRequest(ex.Message);
}
catch (AggregateException ex)
{
return BadRequest(ex.Message);
}
}

Unable to open a realm at path xxx in Xamarin forms

I'm reading data from remote MongoDB realm which syncs to my local realm, but it seems I can't read from my local realm after sync.
This is the message I get when I try to read from my local realm:
Unable to open a realm at path '/data/user/0/com.companyname.appname/files/default.realm': Incompatible histories. Expected a Realm with no or in-realm history, but found history type 3 Path:Exception backtrace:\n<backtrace not supported on this platform>.
Here is my code:
private async Task<Realm> OpenRealm()
{
try
{
var user = App.realmApp.CurrentUser;
//if user is not logged on yet log on the user and sync
if (user == null)
{
var CurrentUser = await App.realmApp.LogInAsync(Credentials.Anonymous());
var config = new SyncConfiguration("Hirschs", CurrentUser);
_realm = await Realm.GetInstanceAsync(config);
return _realm;
}
else
{
return _realm = Realm.GetInstance();
}
}
catch (Exception ex)
{
await UserDialogs.Instance.AlertAsync(new AlertConfig
{
Title = "An error has occurred",
Message = $"An error occurred while trying to open the Realm: {ex.Message}"
});
// Try again
return await OpenRealm();
}
}
The problem here is that you are trying to create a new local realm in the same path where the synced realm already is.
I suppose that you would like to open the same realm synchronously (that is necessary if the device is offline). In this case you would just need to use the same configuration for both the sync and async calls, as reported in the documentation here.
You could do something like:
private async Task<Realm> OpenRealm()
{
try
{
var currentUser = App.realmApp.CurrentUser;
if (currentUser == null)
{
var currentUser = await App.realmApp.LogInAsync(Credentials.Anonymous());
var config = new SyncConfiguration("Hirschs", currentUser);
_realm = await Realm.GetInstanceAsync(config);
return _realm;
}
else
{
var config = new SyncConfiguration("Hirschs", currentUser);
_realm = Realm.GetInstance(config);
return _realm;
}
}
catch (Exception ex)
{
await UserDialogs.Instance.AlertAsync(new AlertConfig
{
Title = "An error has occurred",
Message = $"An error occurred while trying to open the Realm: {ex.Message}"
});
}
}

c# - Ignore exception on client side when server is down

I use RestSharp to pass data between the clien-side (Xamarin android app) and my server.
When there is an error (usually because the server is down) the method that execute the request throw an exception.
I want the exception to go back all the way to the method who called it, so I can throw an error to the user.
For example, I want to login, but lets say the server is down.
A - The method that execute the request
public Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
{
var client = new RestClient
{
BaseUrl = new Uri(BaseUrl),
Authenticator = new HttpBasicAuthenticator(_accountName, _password)
};
var taskCompletionSource = new TaskCompletionSource<T>();
client.ExecuteAsync<T>(request, restResponse =>
{
if (restResponse.ErrorException != null)
{
throw (new Exception("Server returned an error"));
}
taskCompletionSource.SetResult(restResponse.Data);
});
return taskCompletionSource.Task;
}
B - Method that uses method A to execute a request
public static async Task<LoginObject> Login(string accessNumber, string password, string token)
{
var request = new RestRequest
{
Method = Method.POST,
Resource = "Login"
};
request.AddJsonBody(
new
{
accessNumber = accessNumber,
password = password,
token = token
});
var isDone = await Api.ExecuteAsync<LoginObject>(request);
return isDone;
}
C - The method where I want to handle the exception
public async Task Login(string PhoneNumber, string Password)
{
try
{
LoginObject login = await LoginServices.Login(PhoneNumber, Password, Token);
if (login.IsOk)
{
// Move to next activity
}
else
{
Toast.MakeText(this, "Login Error", ToastLength.Short).Show();
}
}
catch (Exception ex) // Here I want to throw the server error
{
Toast.MakeText(this, "Server Error", ToastLength.Short).Show();
return null;
}
}
Now when I run the code, the error is being thrown in A, and the app crash,
I want it to go from A to B and from B to C, and then I'll show an error to the user.
Edit: I tried to put a try/catch block but it still throws the exception in A.
Change method A to have async in the signature and then change your last line to return await taskCompletionSource.Task;
In your A-method, please use taskCompletionSource.SetException like this:
if (restResponse.ErrorException != null)
{
//throw new Exception("Server returned an error");
taskCompletionSource.SetException(new Exception("Server returned an error"));
}
else
{
taskCompletionSource.SetResult(restResponse.Data);
}
In your B-method replace this line:
var isDone = await Api.ExecuteAsync<LoginObject>(request);
with this to re-throw the exception to you C-method:
LoginObject isDone=null;
try
{
isDone = await Api.ExecuteAsync<LoginObject>(request);
}
catch (Exception e)
{
throw e;
}
This article is talking about TaskCompletionSource

Microsoft.Azure.NotificationHub - Async call in sync method

I currently have to provide a sync as async method in my API: Please find the code below. The only problem is that I don’t have a
sync method in the backend. I use Azure.NotificationHub client. That client has only *Async methods. Is my way reasonable?
public PushHubNotificationResult SendPushMessage(string userId, string message)
{
PushHubNotificationResult result = new PushHubNotificationResult();
try
{
result = SendPushMessageAsync(userId, message).GetAwaiter().GetResult();
} catch (Exception ex)
{
result.Status = PushHubNotificationResultType.Error;
result.Error = ex.Message;
result.Exception = ex;
}
return result;
}
public async Task<PushHubNotificationResult> SendPushMessageAsync(string userId, string message)
{
PushHubNotificationResult result = new PushHubNotificationResult();
// EnableTestSend see: https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-push-notification-fixer/#self-diagnose-tips
// Create a new Notification Hub client.
Microsoft.Azure.NotificationHubs.NotificationHubClient hub =
Microsoft.Azure.NotificationHubs.NotificationHubClient.CreateClientFromConnectionString(NotificationHub, NotificationHubName);
// Sending the message so that all template registrations that contain "messageParam"
// will receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
Dictionary<string, string> templateParams = new Dictionary<string, string>();
templateParams["messageParam"] = message;
string userTag = "_UserId:" + userId; // That line sets the IMEI or SerialNo (WLAN only device) == userId to which the push message is sent
try
{
// Send the push notification and log the results.
NotificationOutcome outcome = await hub.SendTemplateNotificationAsync(templateParams, userTag);
result.Status = PushHubNotificationResultType.Success;
foreach (RegistrationResult hubResult in outcome.Results)
{
result.PushNotificationHub = hubResult.ApplicationPlatform;
result.RegistrationId = hubResult.RegistrationId;
result.Outcome = hubResult.Outcome;
}
}
catch (System.Exception ex)
{
result.Status = PushHubNotificationResultType.Error;
result.Error = ex.Message;
result.Exception = ex;
}
return result;
}
thanks for any advice,
Eric
If you want to use sync-over-async, it's very important that you use ConfigureAwait(false) in your async code, otherwise you are very likely to get a deadlock.
NotificationOutcome outcome =
await hub.SendTemplateNotificationAsync(templateParams, userTag).ConfigureAwait(false);
The async method already converts exceptions to PushHubNotificationResultType.Error, why does the sync version do it too?

Trying to call public async Task<Boolean> from a public string submit method

I'm pretty new to this Async thing. I'm trying to write in to an API using a createasync method. However, for some reason I either get an aggregate exception, or the thread just hangs depending on what I've tried. Here is a code example because I have yet to be able to successfully write in to the Salesforce API. I have been able however, to pull back data using similar operations.
Submit Method where I want this all to take place in my controller:
[System.Web.Http.HttpPost]
public string Submit([FromBody]SurveyFormModel survey)
{
// todo - Validate data and stop if bad data comes in.
var report = BuildReport(survey.Questions);
try
{
var task = Task.Run(async () => { await SendReportToSalesforce(survey); });
task.Wait();
}
catch (Exception ex)
{
ex.GetBaseException();
}
EmailExcel(survey);
return JsonConvert.SerializeObject(report);
}
This is the method I'm using to call my salesforceservice.cs
public async Task SendReportToSalesforce([FromBody] SurveyFormModel survey)
{
SalesforceService service = new SalesforceService();
var auth = service.Authenticate();
var sfSurvey = service.SalesForceMapper(survey, survey.AccountDetails);
var result = await service.SendSurveytoSF(auth.Result, sfSurvey); //.Wait();
Console.WriteLine(result);
}
Also included is the salesforceservice class I use to authenticate as well as the method (SendSurveytoSF) that doesnt seem to be working.
public async Task<ForceClient> Authenticate()
{
//get credential values
var consumerkey = ConfigurationManager.AppSettings["consumerkey"];
var consumersecret = ConfigurationManager.AppSettings["consumersecret"];
var username = ConfigurationManager.AppSettings["username"];
var password = ConfigurationManager.AppSettings["password"];
//create auth client to retrieve token
var auth = new AuthenticationClient();
//get back URL and token
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
try
{
await
auth.UsernamePasswordAsync(consumerkey, consumersecret, username, password,
"https://test.salesforce.com/services/oauth2/token");
}
catch (Exception ex)
{
return null;
}
var instanceUrl = auth.InstanceUrl;
var accessToken = auth.AccessToken;
var apiVersion = auth.ApiVersion;
return new ForceClient(instanceUrl, accessToken, apiVersion);
}
public async Task<Boolean> SendSurveytoSF(ForceClient sfclient, Models.Salesforce.Survey survey)
{
survey.Account__c = "0012200000Ah3zG";
var response = await sfclient.CreateAsync("VBR_Assessment__c", survey);
return response.Id != null;
}
I believe I'm maybe just not calling these methods properly, but at this point I really have no clue as I've tried implementing it a ton of different ways. Thank you for any help in advanced!
UPDATE
This is the exception I'm getting:
A first chance exception of type 'Salesforce.Common.ForceException' occurred in mscorlib.dll

Categories