How can I Hash or Encrypt a field with EF CodeFirst? - entity-framework

Using EF Code First, how can I interrupt the saving of a field value so I can hash it? A simple example would be a password field:
public class Account
{
private string _password;
public string Password
{
get
{
return _password;
}
set
{
_password = MyHashMethod(value);
}
}
}
This appears to work when saving the value to the database, but doesn't work when retrieving the value.
EDIT:
Changed _password = MyHashMethod(_password) to MyHashMethod(value) above. Same correction needs to be made in the answer below.

I would just make it like:
public class Account {
public string HashedPassword { get; set; }
public string ClearTextPassword {
set { HashedPassword = MyHashMethod(value); }
}
}
Only HashedPassword is stored in DB.

Related

How to correctly model loosely-typed properties in RavenDB

I am new to RavenDB and looking for guidance on the correct way to store loosely-typed data. I have a type with a list of key/value pairs. The type of the value property isn't known at design time.
public class DescriptiveValue
{
public string Key { get; set; }
public object Value { get; set; }
}
When I query a DescriptiveValue that was saved with a DateTime or Guid Value, the deserialized data type is string. Numeric values appear to retain their data types.
Is there an elegant solution to retain the data type or should I simply store all values as strings? If I go the string route, will this limit me when I later want to sort and filter this data (likely via indexes?)
I hoping this is a common problem that is easily solved and I'm just thinking about the problem incorrectly. Your help is much appreciated!
UPDATE:
The output of this unit test is: Assert.AreEqual failed. Expected:<2/2/2012 10:00:01 AM (System.DateTime)>. Actual:<2012-02-02T10:00:01.9047999 (System.String)>.
[TestMethod]
public void Store_WithDateTime_IsPersistedCorrectly()
{
AssertValueIsPersisted<DateTime>(DateTime.Now);
}
private void AssertValueIsPersisted<T>(T value)
{
ObjectValuedAttribute expected = new ObjectValuedAttribute() { Value = value };
using (var session = this.NewSession())
{
session.Store(expected);
session.SaveChanges();
}
TestDataFactory.ResetRavenDbConnection();
using (var session = this.NewSession())
{
ObjectValuedAttribute actual = session.Query<ObjectValuedAttribute>().Single();
Assert.AreEqual(expected.Value, actual.Value);
}
}
I would expect actual to be a DateTime value.
Absolutely - that's one of the strength of schema-less document databases. See here: http://ravendb.net/docs/client-api/advanced/dynamic-fields
The problem is that RavenDB server has no notion of the type of Value. When sending your object to the server, Value is persisted as a string, and when you later query that document, the deserializer does not know about the original type, so Value is deserialized as a string.
You can solve this by adding the original type information to ObjectValuedAttribute:
public class ObjectValuedAttribute {
private object _value;
public string Key { get; set; }
public object Value {
get {
// convert the value back to the original type
if (ValueType != null && _value.GetType() != ValueType) {
_value = TypeDescriptor
.GetConverter(ValueType).ConvertFrom(_value);
}
return _value;
}
set {
_value = value;
ValueType = value.GetType();
}
}
public Type ValueType { get; private set; }
}
In the setter of Value we also store the type of it. Later, when getting back the value, we convert it back to its original type.
Following test passes:
public class CodeChef : LocalClientTest {
public class ObjectValuedAttribute {
private object _value;
public string Key { get; set; }
public object Value {
get {
// convert value back to the original type
if (ValueType != null && _value.GetType() != ValueType) {
_value = TypeDescriptor
.GetConverter(ValueType).ConvertFrom(_value);
}
return _value;
}
set {
_value = value;
ValueType = value.GetType();
}
}
public Type ValueType { get; private set; }
}
[Fact]
public void Store_WithDateTime_IsPersistedCorrectly() {
AssertValueIsPersisted(DateTime.Now);
}
private void AssertValueIsPersisted<T>(T value) {
using (var store = NewDocumentStore()) {
var expected = new ObjectValuedAttribute { Value = value };
using (var session = store.OpenSession()) {
session.Store(expected);
session.SaveChanges();
}
using (var session = store.OpenSession()) {
var actual = session
.Query<ObjectValuedAttribute>()
.Customize(x => x.WaitForNonStaleResults())
.Single();
Assert.Equal(expected.Value, actual.Value);
}
}
}
}

Entity Framework: Saving of Password as SecureString

In my User class I have the password which is SecureString. To save the password, I have added the UserPassword property.
Sample code:
internal partial class User
{
public string ID { get; set; }
private string _password;
public SecureString Password
{
set { _password = SomePasswordHashing(value.ToString); }
}
public string UserPassword
{
get { return _password; }
set { _password = value; }
}
}
For the saving/retrieving of the UserPassword, does this property need to be public?
Is there a way not to load a UserPassword property (for instance when searching for the users, I would want to exclude loading all users' passwords)?
For the saving/retrieving of the UserPassword, does this property need
to be public?
Yes. EF-Code first needs properties to be public.
Is there a way not to load a UserPassword property (for instance when
searching for the users, I would want to exclude loading all users'
passwords)?
You can transform the results when searching to exclude passwords
var users = db.Users.Where(/* */).Select(u => new User{Name = u.Name});
Or use a DTO class which does not have a password property and return the DTO classes instead of the model object.

How to map a string property to a binary column in the database?

I have a class for a user entity. One of the properties is the user's password (a hash, actually). I made it a string (streamlined code):
public class User
{
public virtual int Id { get; set; }
public virtual string Password { get; set; }
}
There's also a Fluent NHibernate mapping (streamlined code):
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("users");
Id(x => x.Id).GeneratedBy.Sequence("users_id_seq");
Map(x => x.Password); // what do I put here???
}
}
The database column is of bytea data type on PostgreSQL. The above mapping doesn't work, because the property is string (text). What should I do?
you can Make Password a public property, which is only used to reference to the underlying private property HashedPassword.
something like so:
protected virtual byte[] /*or whatever the type is*/ HashedPassword {get; set;}
public virtual string Password
get
{
return (string)(HashedPassword); //or however you want to cast it to string...
}
set
//...
you can then tell fluent nHib to ignore your Password property.
Here is the final solution which works both ways (read & write), what I tried earlier didn't work properly. Hope this will help somebody.
public class User
{
private byte[] _password;
public virtual int Id { get; private set; }
public virtual string Password
{
get { return System.Text.Encoding.Unicode.GetString(_password); }
set { _password = System.Text.Encoding.Unicode.GetBytes(value); }
}
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("users");
Id(x => x.Id).GeneratedBy.Sequence("users_id_seq");
Map(x => x.Password)
.Access.LowerCaseField(Prefix.Underscore)
.CustomType<byte[]>();
}
}

EF Code First CTP5. How to store the Inheritated data from a baseclas

I have a User class that holds some default data.
public class User : BaseEntity
{
//-- Declaration
private string _firstname;
private string _lastname;
private ICollection<BaseProfile> _profiles = new List<BaseProfile>();
//-- Constructor
public User() { }
//-- Properties
public string Firstname
{
get { return _firstname; }
set { _firstname = value; base.Name = string.Format("{0} {1}", this.Firstname, this.Lastname); }
}
public string Lastname
{
get { return _lastname; }
set { _lastname = value; base.Name = string.Format("{0} {1}", this.Firstname, this.Lastname); }
}
public EMailAddress EmailAddress { get; set; }
public SocialSecurityNumber SocialSecurityNumber { get; set; }
public Password Password { get; set; }
public virtual ICollection<BaseProfile> Profiles { get { return _profiles; } set{_profiles = value; }}
}
The Profiles contains diffrent Profiles data based on diffrent profiles the user can have. If the user is a player, then Profiles will contain of a ProfilePlayer clas, if the user would be a Trainer it will contain a ProfileTrainer class. And if the User is a Player and a Trainer it will contain 2 profiles, one ProfilePlayer Class and one ProfileTrainer class. This profile classes would contain information specified for the diffrent profiles the user could be.
Now to my question, how can I tell the EF that it should save the diffrent BaseProfiles as the specified types, cause when EF is createing the databas for me, it's created as a BaseProfiles even if the "real" type is ProfilePlayer class. Do I need to manually create the diffrent tables and then do some mapping or is there a simple way to tell EF to create the diffrent profilesclasses and to save the baseprofiles data into correct table?
I did find the solution to my problem.
modelBuilder.Entity<Domain.BaseProfile>()
.Map<Domain.Model.ProfilePlayer>(p => p.Requires("Discriminator").HasValue("ProfilePlayer"))
.Map<Domain.Model.ProfileTrainer>(p => p.Requires("Discriminator").HasValue("ProfileTrainer"));

what is use of creating property in separate class for each entilty?

I am learning some good code practice that's why i was going through some code, some thing i could not understand in it. It has made property in a separate class for each entity like in userClass it has property
#region public properties
private int uid;
public int userId
{
get { return uid; }
set { uid = value; }
}
private string uName;
public string userName
{
get { return uName; }
set { uName = value; }
}
private string pwd;
public string password
{
get { return pwd; }
// set { pwd = value; }
}
private string uAddress;
public string userAddress
{
get { return uAddress; }
set { uAddress = value; }
}
private string fName;
public string firstName
{
get { return fName; }
set { fName = value; }
}
private string lName;
public string lastName
{
get { return lName; }
set { lName = value; }
}
private string uPhone;
public string userPhone
{
get { return uPhone; }
set { uPhone = value; }
}
private string uMobile;
public string userMobile
{
get { return uMobile; }
set { uMobile = value; }
}
private int secretQuestion;
public int securityQuestion
{
get { return secretQuestion; }
set { secretQuestion = value; }
}
private string userAnswer;
public string answer
{
get { return userAnswer; }
set { userAnswer = value; }
}
#endregion
and from the business logic class it uses the property instead of using directly any entity's attribute name, but i am confuse whats there need to make a property like this?
other then this it has got enums for database column name which has a clear reason behind this that if in near future we have to change the database table's fields name then we don't have to change through out the whole business logic class and we can make changes to enum directly, But what is there use of creating property like this please elaborate me on this
Are you really asking why it uses properties instead of having public fields?
Fields are an implementation detail - they're how data is stored, which shouldn't be something the outside world cares about, at least for 99% of types. Properties are part of the contract that a type has in terms of its API - the implementation is up to the type. In other words, it's a matter of encapsulation. Properties can be expressed in interfaces, as abstract methods etc, precisely because they keep the contract and the implementation separate.
Additionally, properties make databinding, debugging and various other things simpler. I have an article about why properties matter, which you may find useful.
Having said all of this, those properties are implemented in a tedious way - and they don't obey .NET naming conventions. I would have written them as:
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
// etc
Properties can be defined on Interfaces, but member fields cannot. So if you needed to refactor this class to a class that implements an interface, you can put the properties on the interface (and then have other classes that implement them as well.)
Some similar questions:
Public Fields versus Automatic Properties
Property vs public field.
In additional to above: Actually you can easily decide public field or property by yourself. It is quite easier to understand that:
(1) Name is a property of class Person
(2) Speed is a property of class Plane
(3) Empty is a public field of class String. If you say String has a property named Empty, it's really weird. And String has a property Length is easy to understand.