SQL table is remembering data that has been deleted (MVC/C#) - c#

I've deleted one of the registered users from the data base manually, by right-clicking on the table row itself and selecting the delete option. Now I am trying to register the same user again with exactly the same email that this particular user use to be registered before. When I run the registration process, the email duplicate method is constantly returning true for some reason. If I try to use any other email for registering it works like charm. Any idea why is this happening?
Email validation method
private static bool EmailIsRegistered(string email)
{
using (var data = new HospitalDBDataContext())
{
if (data.Connection.State == ConnectionState.Closed) data.Connection.Open();
var match = data.Staffs.Any(x => x.Email.Equals(email));
if (data.Connection.State == ConnectionState.Open) data.Connection.Close();
data.Dispose();
return match;
}
}

Related

How to insert or update properties in Active Directory Users and Groups

I am making a windows application that sync the source data to Active Directory.
This application works like this.
Choose Source Data(Department, User)
Mapping user or department attributes from source data
When Application service is run, it create groups and users in Active Directory
And also it sets the attributes to users and groups.
When I try to set group or user attributes(properties), it throws exception message like this.
in DirectoryEntry.CommitChanges(); block
The directory
service cannot perform the requested operation on the RDN attribute of an object.
I tried to solve it, but it's really hard to me because I`m not good at Active directory...
Code is below, Please share your knowledge.
//ppk: department key column, pk:user key column, row : Source DataTable's row
void CreateADUser(string ppk,string pk,DataRow row)
{
//password
string pass = GetPass(pk,row,LogSections.AD);
//OU
DirectoryEntry addept = adm.FindOU(ppk);
//principal path
string sOU = adm.GetPrincipalPath(addept);
var aduser = adm.CreateNewUser(sOU, pk, pass, pk, null, null, adm.sDomain);
SetAdUserProperties(pk, pass, row);
MoveUser(ppk,pk);
}
void SetAdUserProperties(string pk,string pass,DataRow row)
{
if (row == null) return;
//list of mapped column(AD User attributes)
List<ADMapping> MappingPatterns = GetAdMappings(Words.User,false);
//Columns name of Source Data table's row
var colnames = Tool.GetColNames(row);
//get user proterties
var aduser = adm.GetUser(pk);
//directory entry of users
var de=aduser.GetUnderlyingObject() as DirectoryEntry;
//looping mapped column of user attributes
foreach (var ADMap in MappingPatterns)
{
string val = ADMap.Mapping;
//mapped columns value
val=Util.ReplaceColPattern(val, row);
SetProperty(de, ADMap.CN, val);
}
if (!string.IsNullOrWhiteSpace(pass))
{
var UserPkColumn = AppConfigHelper.GetAppString(Words.SourceUserPKColumn);
UserPkColumn = Util.GetActualColName(UserPkColumn);
aduser.SetPassword(pass);
QueryHelper.Update(QueryHelper.ConnectionString, Words.ShadowUserTable
,new SqlParameter[] { new SqlParameter("#passwd", pass) }
, new SqlParameter("#"+UserPkColumn,pk));
}
aduser.Save();
}
public void SetProperty(DirectoryEntry oDE, string sPropertyName, object sPropertyValue)
{
if (sPropertyValue != null && !string.IsNullOrWhiteSpace(sPropertyValue.ToString()))
{
if (oDE.Properties.Contains(sPropertyName))
{
oDE.Properties[sPropertyName].Value = sPropertyValue;
}
else
{
oDE.Properties[sPropertyName].Add(sPropertyValue);
}
try
{
oDE.CommitChanges(); //exception here.
oDE.Close();
}
catch (Exception)
{
}
}
}
I also asked this question to other forums, and finally got it.
Before DirectoryEntry.CommitChanges(); set UserPropertyCache property to true
and call the RefreshCache method.
It's hard to see what's the cause of the issue here as we're not seeing what attributes you are trying to set.
That said, you can't just add an attribute if it doesn't exist on your AD object so this part of your code definitely has an issue :
if (oDE.Properties.Contains(sPropertyName))
{
oDE.Properties[sPropertyName].Value = sPropertyValue;
}
else
{
//The following line will never work in this context
oDE.Properties[sPropertyName].Add(sPropertyValue);
}
If I had to make an educated guess, I'd say you're either trying to set an attribute that can't be set, or the User you're adding doesn't have all it's mandatory attributes set.

Asp.Net Identity - Custom Database Access UserManager

Is is possible to extend the UserStore/UserManager to have access to a custom table within an override method (without creating another dbcontext)?
I'm working on a legacy database which we integrated with Identity. Recently we added a new table, Clients, to the database that has a one to one relationship with the Users table. What would like to do is override the FindAsync method in the UserManager class to do call the base method, grab the user, and then based on the user's client Id stored in the table, fetch the client name and insert that into the user model.
The following is what I have attempted; however, to me I think this is wrong approach and would like some suggestions on how to correctly apply what I'm trying to do.
public override async Task<ApplicationUser> FindAsync(string userName, string password)
{
ApplicationUser user = await base.FindAsync(userName, password);
if (user != null && user.ClientID != null)
{
using (var ctx = new ApplicationDbContext(HostPage.ConnectionString))
{
user.Client = ctx.Clients.Where(p => p.ClientID == user.ClientID).FirstOrDefault();
}
}
return user;
}
You could modify SQL in base.FindAsync() to perform a join to your table thus executing a single query.

Add method - MVC - working with data entry into two tables

I have two classes:
**User
UseP where** User have its id (PK) and UserP has the id (FK) of User.
I'm working on MVC 4. Using Fluent API.
The classes are mapped within the project to connect to the database. My project is split into controllers, services, models and views.
I have a User screen that uses a UserPr field.
How can I instantiate it in class without being the way down? (that way does not work because of the relationship, otherwise work):
**CLASS USER.CS**
public string Login { get { return this.UserP.login } set { login = value }}
inclusion screen to add the User of items, I should also change the status of the screen, this status is within UserP.
Controller
public ViewResultBase Add(User model)
{
if (this.ModelState.IsValid)
{
try
{
this.Service.SaveUserP(model);
return this.SuccessView(true);
}
catch (ValidationException exception)
{
base.AddValidationErrors(exception);
return base.PartialView(model);
}
}
else
{
return base.PartialView(model);
}
}
Service
public void SaveUserP(User item)
{
//save fields from User (Running ok)
base.context.Usuario.Add(item);
//Attempt to save the login and their status in UserP
foreach (var userP in base.context.UserP.Where(x => x.IdUser == item.Id))
{
item.login = userP.Login;
userP.ParticipantType = 3;
base.context.UsersP.Add(userP);
}
}
I've tried that way, but I could not.
If the item.login is only working because login stand as [notmapped] in User.cs
To summarize: In the inclusion screen (User) I have a field that should bring (UserP) login.
When I trigger the method of inclusion, he should save the fields and save the User log in using UsuarioP IdUsuario as key and also changing the status of login (ParticipantType = 3)
The error I get:
Invalid column login (because really there is no login in User)
Time to debug it includes only the User fields, and even through the foreach.
I do not know how to operate, can help me? What if I have not been clear, I put more details
You will need to save the User input first before your foreach loop.
base.context.SaveChanges();

How do I update a field in the database before my transaction is committed?

I am working on a password change method, this view is enforced by one of many conditions. The first condition is if the LastLoggedin field in the database is null. I have this field set to null in my test database to force the password change events.
I have coded a method to change the password after performing some tests, but I cannot get past the first test because the controller method that the click event calls returns the user back to the log on method, which in turns checks the LastLoggedin field in the database which is still null because I have not yet logged in. I tried to change that value from within my change password method using the following code:
public bool SavePassword(UserModel user, PasswordRecoveryModel password)
{
try
{
string newPass = password.PasswordNew;
string newHash = PasswordManager.EncryptPassword(newPass);
User domainObject = UnitOfWork.UserRepository.GetItem(user.EntityId);
bool hasUsedPassword = UnitOfWork.UserRepository.HasHadPassword(domainObject, newHash, DateTime.Now.AddMonths(-6));
if (hasUsedPassword.Equals(true))
{
return true;
}
User lastLogged = UnitOfWork.UserRepository.GetItem(user.EntityId);
lastLogged.LastLoggedIn = DateTime.Now;
lastLogged.VerifiedOn = DateTime.Now;
UnitOfWork.UserRepository.Update(lastLogged);
lastLogged.VerifiedOn.Equals(DateTime.Now);
lastLogged.LastLoggedIn.Equals(DateTime.Now);
user.Password = newHash;
user = SaveModel(UnitOfWork.UserRepository,
user,
Mapper.User.ModelToDomain,
Mapper.User.DomainToUserModel);
CommitTransaction();
return false;
}
catch (Exception ex)
{
OnServiceException(ex);
throw;
}
}
But I am still not getting anything other than the new password saved in the database, I am verifying this by running a query on my username. How do I update this field so I can get by this test on password change, and is it even acceptable to do this? In our old product it was done in a very complex manner creating a temporary user object ant using that to get past the test and on to the next test. I am trying to simplify the process.
I am new to MVC and programming in general any help would be appreciated.
EDIT found my problem, as usual over thinking the issue, here is the updated code:
if (hasUsedPassword.Equals(true))
{
return false;
}
user.LastLoggedIn = DateTime.Now.ToString();
user.Password = newHash;
user = SaveModel(UnitOfWork.UserRepository,
user,
Mapper.User.ModelToDomain,
Mapper.User.DomainToUserModel);
CommitTransaction();
return true;

Asp.Net web forms log in schema - Keep a list of logged in users

i'm a beginner at developing a whole system so, need some approach guidance here folks. Hope you can help me! =)
In a try to create a log in schema, i have a Control class which keeps a list of logged users.
public static class ControleAcesso
{
private static List<Associado> associadosLogados = new List<Associado>();
public static Mensagens doLogin(Page pagina, String login, String senha)
{
Mensagens retorno = new Mensagens();
retorno = AcessoDAL.Login(login, senha);
if (retorno.Erros.Count() <= 0 && retorno.Objeto != null)
{
Associado assocLogado = new Associado();
Associados assocEncontrado = (Associados)retorno.Objeto;
assocLogado.ID = assocEncontrado.Associado;
assocLogado.Nome = assocEncontrado.Nome;
assocLogado.Nome_Fantasia = assocEncontrado.Nome_Fantasia;
assocLogado.Data_Inclusao = assocEncontrado.Data_Inclusao;
assocLogado.Email = assocEncontrado.Email;
assocLogado.Data_Alteracao = assocEncontrado.Data_Alteracao;
assocLogado.Login = assocEncontrado.Login;
assocLogado.Senha = assocEncontrado.Senha;
assocLogado.CGC_CPF = assocEncontrado.CGC_CPF;
assocLogado.SessionID = pagina.Session.SessionID;
var associadoJaLogado = associadosLogados.Where(x => x.ID == assocLogado.ID).FirstOrDefault();
if (associadoJaLogado != null)
{
pagina.Session.Remove(associadoJaLogado.SessionID);
associadosLogados.Remove(associadoJaLogado);
}
associadosLogados.Add(assocLogado);
}
return retorno;
}
}
So, this method basicaly do the login call to a Data Access Layer class. If the log in returns a user, i do Add this user to my list.
So, to later know my logged in users and retrieve data about then just using my session ID, i do some management in the list. Just the basic. Removing the logged in one and adding the new one.
The problem, as you probably noticed, is that, when i have two requests for the same credentials at the "same" time, it would allow the user to log in two times.
So, is this the best practice for log in schemes? Would you guys suggest me to change something?
I'm using ASP.NET Web Forms with C#.
Thank you in advice.
Unless you explicitly want to force your users to use your application with one device at a time, you should not worry about the possibility that they might log in. So this is a problem if and only if it can violate one of your terms.

Categories

Resources