I have a form on a mvc view that contains Name, Username, email address, drop down list for branch and department. There are 2 stored procedures that is checking for duplicate Username and Email address. An error will be shown if the user clicks the update button.
Scenario 1
If the user deletes the username and enters a unique one the form will not submit because email address is still existent in the database.
How can I allow the update to continue if the user puts back the original Username
[HttpPost]
public async Task<IActionResult> Update(ApplicationUserModel model)
{
var appmodel = new ApplicationUserModel();
appmodel.UserDetails = await ClaimsService.GetApplicationUserByID(model.Users.UserID);
appmodel.Users = await ClaimsService.GetUserNameByID(model.Users.UserName);
appmodel.User = await ClaimsService.GetEmailAddressIfExists(model.Users.EmailAddress);
if (!appmodel.UserDetails.Name.Equals(model.Users.Name) || appmodel.UserDetails.BranchID != model.Users.BranchID || appmodel.UserDetails.DepartmentID != model.Users.DepartmentID )
{
if(!appmodel.UserDetails.UserName.Equals(model.Users.UserName) || !appmodel.UserDetails.EmailAddress.Equals(model.Users.EmailAddress))
{
model.UserNameErrorMessage = "Username already exists";
model.EmailAddressErrorMessage = "Email address already exists";
model.Username = appmodel.Users.UserName;
model.EmailAddress = appmodel.User.EmailAddress;
model.Users = new Model.Applications.Tables.tblUsers() { Archive_User = "0", StatusID = 1 };
model.BranchSelectList = new SelectList(await BranchServices.GetBranchByCompanyID(1), "BranchID", "BranchFullName");
model.DepartmentSelectList = new SelectList(await DepartmentService.GetAllActiveDepartments(1), "DepartmentID", "Department");
return View(model);
}
}
await ClaimsService.UpdateUserAsync(model.Users);
string redirectUrl = string.Format("/ApplicationUsers/Users");
return RedirectToAction("Message", "Home", new { type = Service.Utils.StringHelper.Types.UpdateSuccess, url = redirectUrl });
}
Compare the old value (of username alone then email) with the new value if they are the same then don't check if it exists before. if they are different then check if the new is unique
If email was 'user1#example.com' , username = 'user1'
and the he entered email = 'user1#eample.com' but username = 'user1updated'
You first check old email and new email (both are 'user1#example') then it is ok.
then check the old username with the new username (here are different) so I check the existence of new username ('user1updated') in the database if it not there I update otherwise don't update
[HttpPost]
public async Task<IActionResult> Update(ApplicationUserModel model)
{
string redirectUrl;
var appmodel = new ApplicationUserModel();
appmodel.UserDetails = await ClaimsService.GetApplicationUserByID(model.Users.UserID);
appmodel.Users = await ClaimsService.GetUserNameByID(model.Users.UserName);
appmodel.User = await ClaimsService.GetEmailAddressIfExists(model.Users.EmailAddress);
if(appmodel.UserDetails.EmailAddress == model.Users.EmailAddress || appmodel.UserDetails.UserName == model.Users.UserName)
{
if (!appmodel.UserDetails.Name.Equals(model.Users.Name) || appmodel.UserDetails.BranchID != model.Users.BranchID || appmodel.UserDetails.DepartmentID != model.Users.DepartmentID)
{
await ClaimsService.UpdateUserAsync(model.Users);
redirectUrl = string.Format("/ApplicationUsers/Users");
return RedirectToAction("Message", "Home", new { type = Service.Utils.StringHelper.Types.UpdateSuccess, url = redirectUrl });
}
else if (appmodel.UserDetails.EmailAddress != model.Users.EmailAddress || appmodel.UserDetails.UserName != model.Users.UserName)
{
if (!appmodel.UserDetails.Name.Equals(model.Users.Name) || appmodel.UserDetails.BranchID != model.Users.BranchID || appmodel.UserDetails.DepartmentID != model.Users.DepartmentID)
{
await ClaimsService.UpdateUserAsync(model.Users);
redirectUrl = string.Format("/ApplicationUsers/Users");
return RedirectToAction("Message", "Home", new { type = Service.Utils.StringHelper.Types.UpdateSuccess, url = redirectUrl });
}
if(appmodel.UserDetails.EmailAddress == model.Users.EmailAddress)
{
model.EmailAddressErrorMessage = "";
}
if(appmodel.UserDetails.EmailAddress != model.Users.EmailAddress)
{
model.EmailAddressErrorMessage = "Email address already exists";
}
if(appmodel.UserDetails.UserName == model.Users.UserName)
{
model.UserNameErrorMessage = "";
}
if (appmodel.UserDetails.UserName != model.Users.UserName)
{
model.UserNameErrorMessage = "Username already exists";
}
model.Username = appmodel.Users.UserName;
model.EmailAddress = appmodel.User.EmailAddress;
model.Users = new Model.Applications.Tables.tblUsers() { Archive_User = "0", StatusID = 1 };
model.BranchSelectList = new SelectList(await BranchServices.GetBranchByCompanyID(1), "BranchID", "BranchFullName");
model.DepartmentSelectList = new SelectList(await DepartmentService.GetAllActiveDepartments(1), "DepartmentID", "Department");
return View(model);
}
await ClaimsService.UpdateUserAsync(model.Users);
redirectUrl = string.Format("/ApplicationUsers/Users");
return RedirectToAction("Message", "Home", new { type = Service.Utils.StringHelper.Types.UpdateSuccess, url = redirectUrl });
}
if (appmodel.UserDetails.EmailAddress == model.Users.EmailAddress)
{
model.EmailAddressErrorMessage = "";
}
if (appmodel.UserDetails.EmailAddress != model.Users.EmailAddress)
{
model.EmailAddressErrorMessage = "Email address already exists";
}
if (appmodel.UserDetails.UserName == model.Users.UserName)
{
model.UserNameErrorMessage = "";
}
if (appmodel.UserDetails.UserName != model.Users.UserName)
{
model.UserNameErrorMessage = "Username already exists";
}
model.Username = appmodel.Users.UserName;
model.EmailAddress = appmodel.User.EmailAddress;
model.Users = new Model.Applications.Tables.tblUsers() { Archive_User = "0", StatusID = 1 };
model.BranchSelectList = new SelectList(await BranchServices.GetBranchByCompanyID(1), "BranchID", "BranchFullName");
model.DepartmentSelectList = new SelectList(await DepartmentService.GetAllActiveDepartments(1), "DepartmentID", "Department");
return View(model);
}
Related
I'm just not getting this.
So I have a list from my API
Of Customers called a
I need to validate weather the fields correlate to any of the 100+ Logins that I'm suppose to receive from the Resposne
How I'm Going about it At the moment
foreach (var c in Users.a)
{
if (Email == c.email && Password == c.password)
{
await App.Current.MainPage.DisplayAlert("Login Success", "", "Ok");
Application.Current.Properties["Email"] = c.email;
Application.Current.Properties["Userid"] = c.id;
Users.Loggedin = true;
await Application.Current.SavePropertiesAsync();
await App.Current.MainPage.Navigation.PushAsync(new Home(c.email));
}
else
{
await App.Current.MainPage.DisplayAlert("Login Fail", "Please enter correct Email and Password", "OK");
}
}
Am I doing this wrong? Is there a better way of doing this.
The Call
RestAPI rest = new RestAPI("http://Site/wp-json/wc/v3/",
"ck_a25f******************dcd0",
"cs_8f247c22************05c");
WCObject wc = new WCObject(rest);
var x = await wc.Customer.GetAll();
Users.a = x;
I Came to the Conclusion that my best way forward with this was to Fetch => Add => Combine Until My list was empty.
RestAPI rest = new RestAPI("http://Yoursite/wp-json/wc/v3/", "Customer Key", "Customer Secret");
WCObject wc = new WCObject(rest);
int pageNum = 1;
var isNull = false;
List<Customer> oldlist;
while (!isNull)
{
var page = pageNum.ToString();
x = await wc.Customer.GetAll(new Dictionary<string, string>() {
{
"page", page
}, {
"per_page", "100"
}
});
oldlist = FetchCustomers.customers ?? new List<Customer>();
if (x.Count == 0) {
break;
}
else
{
pageNum++;
FetchCustomers.customers = oldlist.Union(x).ToList();
}
}
How i'm Validating
var list = FetchCustomers.customers.ToList();
foreach (var user in list)
{
if (user.username == Usernamelabel.Text)
{
Application.Current.Properties["CId"] = user.id;
Application.Current.Properties["CEmail"] = user.email;
Application.Current.Properties["CUsername"] = user.username;
Users.Loggedin = true;
Application.Current.SavePropertiesAsync();
App.Current.MainPage.DisplayAlert("Empty Values", "Phase 2 Done your logged in ", "OK");
}
}
User is Validated From username I'm busy with another Process to Validate the user by The Wordpress API and getting a JWT token then Sending it to this Method to validate and Fetch the Customer and then Persisting the User.
Here's that Extra Method I mentioned
var client = new WordPressClient("http://Youtsite/wp-json/");
client.AuthMethod = AuthMethod.JWT;
await client.RequestJWToken(USername, Password);
var x = client;
var isValidToken = await client.IsValidJWToken();
WpApiCredentials.token = client.GetToken();
if (isValidToken)
{
Login_Phase2();
}
else
{
await App.Current.MainPage.DisplayAlert("Empty Values", "Token not Found", "OK");
}
#endregion
I am using this method for Reset Password
public ResetTokenResult DoPasswordResetTokenForChange(string userId, string token)
{
switch (UserManager.FindById(userId))
{
case null:
return ResetTokenResult.UnknownUserId;
case CatalystUser user when ! (user.PasswordInvalidatedByReset ?? false):
return ResetTokenResult.TokenIsExpired;
case CatalystUser user when ! ((user.PasswordResetTokenExpiration ?? DateTime.MinValue) > DateTime.UtcNow):
return ResetTokenResult.TokenIsExpired;
case CatalystUser user when UserManager.VerifyUserToken(user.Id, "ResetPassword", token):
user.PasswordResetTokenExpiration = DateTime.UtcNow.AddDays(-1); // 1-time use. Invalidate now.UserManager.Update(user);
return ResetTokenResult.Success;
default:
return ResetTokenResult.InvalidToken;
}
}
Controller which I am using this method
[RequireHttpsWhenConfigured]
public async Task<ActionResult> Index(PasswordChangePage currentPage,
string userId, string token, string returnUrl = "")
{
var model = new PasswordChangePageViewModel(currentPage);
var isResetPasswordRequest = !string.IsNullOrEmpty(userId) && !string.IsNullOrEmpty(token);
if (!isResetPasswordRequest)
{
if (!RequestContext.IsCurrentUserAuthorized())
return Redirect(NavigationService.GetLoginLink());
model.PasswordChangeModel = new PasswordChangeViewModel {ReturnUrl = returnUrl};
model.ReturnUrl = returnUrl;
return View("Index", model);
}
if (RequestContext.IsCurrentUserAuthorized())
{
SignInManager.AuthenticationManager.SignOut();
return Redirect(Request.Url?.AbsoluteUri ?? "~/");
}
var loginLink = NavigationService.GetLoginLink();
var result = UserAccountService.DoPasswordResetTokenForChange(userId,Base64ForUrlDecode(token));
if ((result & ResetTokenResult.Failure) != ResetTokenResult.None)
{
model.ChangeCanProceed = false;
model.ErrorMessage = GetMessageForTokenResult(result);
model.LoginLink = loginLink;
}
else
{
model.PasswordChangeModel = new PasswordChangeViewModel { CurrentPassword = "null", IsResetPassword = true, UserId = userId, ResetPasswordToken = token };
model.ReturnUrl = loginLink;
}
return View("Index", model);
}
When users want to reset their password, they receive an email with a token link and everything works fine. As I know default ASPNET Identity token burns after 1 clicking to link.
My question is what is the best way to implement logic, the token link will burn after 5 clickings to link which is sent to email.
I developed function to delete users (soft deletion), ie stays in the database and does not show in the list. When I enter the login and password of the deleted account, it have to show a message as this login is deleted.
how to achieve this and thanks
user.controller.cs:
[Route("api/Users/Login")]
[ResponseType(typeof(object))]
public async Task<object> accountLogin(string name, string password)
{
string pwd = Encrypt(password);
Users account = new Users();
var query = from c in db.Users
where c.userlogin == name && c.password == pwd
select c;
account = query.FirstOrDefault();
string message = "";
if (account == null)
{
message += "404";
}
else if (account .IsActive == 1)
{
message += "400";
}
else if ((account .IsActive != 0) && (account .IsActive != 1)) // this condition of account deleted -- or account .IsActive == 2
{
message += "500";
}
else
{
message = JsonConvert.SerializeObject(account);
}
return new { a = message };
}
and this login.controller.js:
$scope.login = function () {
$scope.loading = true;
authService.login($scope.userlogin)
.then(function done(response) {
console.log(response);
if (response.a == '400') {
$scope.error = 'account disabled';
$scope.loading = false;
}
else if (response.a == '500') {
$scope.error = 'this login is deleted';
$scope.loading = false;
}
else if (response != '404') {
console.log("bbb");
$location.url('Dashboard');
}
else {
console.log("login or password incorrect");
$scope.error = 'login or password incorrect';
$scope.loading = false;
}
},
function fail(err) {
$scope.error = 'Problem in connextion ! contact administrateur';
console.log(err);
}
);
}
This is action from my controller
[HttpPost]
[AjaxAction]
public ActionResult Registration(RegisterUserModel registerUser)
{
var data;
if (ModelState.IsValid)
{
if (!IsUserExist(registerUser.Email))
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(registerUser.Password);
var newUser = _db.Users.Create();
newUser.Name = registerUser.Name;
newUser.Email = registerUser.Email;
newUser.Type = UserType.User.ToString();
newUser.Password = encrpPass;
newUser.PasswordSalt = crypto.Salt;
_db.Users.Add(newUser);
_db.SaveChanges();
data = new { status = "OK", message = "Success" };
}
else
{
data = new { status = "ERROR", message = "User already exists" };
}
}
else
{
data = new { status = "ERROR", message = "Data is incorrect" };
}
return Json(data, JsonRequestBehavior.AllowGet);
}
but I don't know how to initialize data variable in the right way, because I need to set different values in different cases. What is the right way to do that?
I usually use multiple return statements to avoid having to declare an object like
if(something){
return Json(new{status = "status 1", message = "message1"})
}
else{
return Json(new{status = "status 2", message = "message2"})
}
you can try this:
var data = new object();
Here is one of the options
[HttpPost]
[AjaxAction]
public ActionResult Registration(RegisterUserModel registerUser)
{
JsonResult data;
if (ModelState.IsValid)
{
if (!IsUserExist(registerUser.Email))
{
var crypto = new SimpleCrypto.PBKDF2();
var encrpPass = crypto.Compute(registerUser.Password);
var newUser = _db.Users.Create();
newUser.Name = registerUser.Name;
newUser.Email = registerUser.Email;
newUser.Type = UserType.User.ToString();
newUser.Password = encrpPass;
newUser.PasswordSalt = crypto.Salt;
_db.Users.Add(newUser);
_db.SaveChanges();
data = Json(new { status = "OK", message = "Success" }, JsonRequestBehavior.AllowGet);
}
else
{
data = Json(new { status = "ERROR", message = "User already exists"}, JsonRequestBehavior.AllowGet);
}
}
else
{
data = Json(new { status = "ERROR", message = "Data is incorrect" }, JsonRequestBehavior.AllowGet);
}
return data;
}
You can use the dynamic keyword.
dynamic data;
I'm still very new to C# and would appreciate any help with my code.
I'm creating a user profile page and am getting the error "Nullable object must have a value" on "photo = (byte)user.Photo;" in the following code. I assume it's because I declared "photo = 0;" How do I add a value to it?
Update:
Here's the entire method
public static bool UserProfile(string username, out string userID, out string email, out byte photo)
{
using (MyDBContainer db = new MyDBContainer())
{
userID = "";
photo = 0;
email = "";
User user = (from u in db.Users
where u.UserID.Equals(username)
select u).FirstOrDefault();
if (user != null)
{
photo = (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}
}
}
I am assuming that you are getting error for this one...
if (user != null)
{
photo = (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}
If yes then just replace it with...
if (user != null)
{
photo = user.Photo== null ? null : (byte)user.Photo;
email = user.Email;
userID = user.UserID;
return true; // success!
}
else
{
return false;
}