Inheritance: INotifyPropertyChanging, INotifyPropertyChanged
Ejemplo n.º 1
0
 partial void UpdateUserAttribute(UserAttribute instance);
Ejemplo n.º 2
0
 partial void DeleteUserAttribute(UserAttribute instance);
Ejemplo n.º 3
0
 partial void InsertUserAttribute(UserAttribute instance);
Ejemplo n.º 4
0
        /// <summary>
        /// Update an existing attribute to the same value (provided for performance sake) but with the latest key version.
        /// 
        /// Requires a subsequent call to SubmitChanges on Current.WriteDB
        /// </summary>
        public bool UpdateAttribute(string value, byte attribute, out string message)
        {
            using (MiniProfiler.Current.Step("UpdateAttribute"))
            {
                var db = Current.WriteDB;

                var toUpdate =
                    (from user in db.Users
                     join attr in db.UserAttributes on user.Id equals attr.UserId
                     where attr.UserAttributeTypeId == attribute && user.Id == this.Id
                     select attr).SingleOrDefault();

                if (value.IsNullOrEmpty())
                {
                    if (toUpdate != null)
                    {
                        db.UserAttributes.DeleteOnSubmit(toUpdate);
                    }

                    message = null;
                    return true;
                }

                if (toUpdate == null)
                {
                    toUpdate = new UserAttribute();
                    toUpdate.CreationDate = Current.Now;
                    toUpdate.UserId = this.Id;
                    toUpdate.UserAttributeTypeId = attribute;

                    db.UserAttributes.InsertOnSubmit(toUpdate);
                }

                string iv, hmac;
                byte version;
                var updated = Current.Encrypt(value, out iv, out version, out hmac);

                if (updated.Length > 267)
                {
                    message = UserAttributeTypeId.GetDisplayName(attribute) + " is too long.";
                    return false;
                }

                toUpdate.Encrypted = updated;
                toUpdate.IV = iv;
                toUpdate.KeyVersion = version;
                toUpdate.HMAC = hmac;

                message = null;
                return true;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Create a new account given an email and password
        /// </summary>
        public static bool CreateAccount(string email, PendingUser pendingUser, DateTime now, string vanity, string realname, out User created, out string errorMessage)
        {
            email = email.ToLowerInvariant();

            if (vanity.HasValue() && !Models.User.IsValidVanityId(vanity, out errorMessage))
            {
                created = null;

                return false;
            }

            var db = Current.WriteDB;

            // Quick check to make sure the vanity id is not in use elsewhere
            if (vanity.HasValue() && db.Users.Any(u => u.VanityProviderId == vanity))
            {
                created = null;
                errorMessage = "That Vanity OpenId is already in use";

                return false;
            }

            var provider = Current.UniqueId();

            // Odds of colision are miniscule, but might as well check
            while (db.Users.Any(u => u.ProviderId == provider))
                provider = Current.UniqueId();

            // We need to compute these way before we use them for some length checks
            byte emailVersion;
            string emailIV, emailHMAC;
            var emailEncrypted = Current.Encrypt(email, out emailIV, out emailVersion, out emailHMAC);

            byte nameVersion = 0xFF;
            string nameEncrypted= null, nameIV = null, nameHMAC = null;

            if (realname.HasValue())
            {
                nameEncrypted = Current.Encrypt(realname, out nameIV, out nameVersion, out nameHMAC);
            }

            if (emailEncrypted.Length > 267)
            {
                created = null;
                errorMessage = "Email is too long";

                return false;
            }

            if (nameEncrypted.HasValue() && nameEncrypted.Length > 267)
            {
                created = null;
                errorMessage = "Name is too long";

                return false;
            }

            string emailHash;
            byte emailSaltVersion;
            emailHash = Current.SystemHash(email, out emailSaltVersion);

            var newUser =
                new User
                {
                    LastActivityDate = DateTime.UtcNow,
                    EmailHash = emailHash,
                    EmailSaltVersion = emailSaltVersion,
                    ProviderId = provider,
                    PasswordHash = pendingUser.PasswordHash,
                    PasswordSalt = pendingUser.PasswordSalt,
                    CreationDate = now,
                    VanityProviderId = vanity,
                    UserTypeId = Models.UserTypeId.Normal
                };

            try
            {
                db.Users.InsertOnSubmit(newUser);
                db.SubmitChanges();
            }
            catch (Exception e)
            {
                // Hack: There isn't really a nice way to detect a unique constraint conflict,
                //       so... check the message.  Checking for the constraint name so this isn't
                //       *guaranteed* to break on non-English language systems... still not guaranteed
                //       to work though.
                if(e is System.Data.SqlClient.SqlException && e.Message.Contains("Users_EmailHash_EmailSaltVersion"))
                {
                    created = null;
                    errorMessage = "Email address already registered.";
                    return false;
                }

                Current.LogException(e);
                created = null;
                errorMessage = "User account could not be created.";
                return false;
            }

            // Open season on this user until the context is torn down.
            db.LiftUserRestrictionsOnId = newUser.Id;

            // Can't put a unique constrain on VanityProviderId (as its normally null), so
            //    this is a hack to make sure no two users end up slipping in and getting the 
            //    same vanity id.
            if (vanity.HasValue() && db.Users.Count(u => u.VanityProviderId == vanity) != 1)
            {
                newUser.VanityProviderId = null;
                db.SubmitChanges();
            }

            var emailAttr =
                new UserAttribute
                {
                    UserId = newUser.Id,
                    CreationDate = now,
                    UserAttributeTypeId = UserAttributeTypeId.Email,
                    Encrypted = emailEncrypted,
                    IV = emailIV,
                    KeyVersion = emailVersion,
                    HMAC = emailHMAC
                };

            db.UserAttributes.InsertOnSubmit(emailAttr);
            db.SubmitChanges();

            if (realname.HasValue())
            {
                var nameAttr =
                    new UserAttribute
                    {
                        UserId = newUser.Id,
                        CreationDate = now,
                        UserAttributeTypeId = UserAttributeTypeId.RealName,
                        Encrypted = nameEncrypted,
                        IV = nameIV,
                        KeyVersion = nameVersion,
                        HMAC = nameHMAC
                    };

                db.UserAttributes.InsertOnSubmit(nameAttr);
                db.SubmitChanges();
            }

            created = newUser;
            errorMessage = null;

            return true;
        }
Ejemplo n.º 6
0
        public void UserAttributeInsertWithUserId()
        {
            var r = new Restrictions();

            var attr = new UserAttribute
            {
                UserId = 1
            };

            var updates = new Dictionary<object, Restrictions.ShadowModifiedMember[]>();

            string ignored;
            Assert.IsTrue(r.IsValidChangeSet(updates, new List<object>(), new List<object>() { attr }, new List<object>(), new List<int>() { 1 }, out ignored));
        }
Ejemplo n.º 7
0
        public void UserAttributeUpdateWithUserId()
        {
            var r = new Restrictions();

            var attr = new UserAttribute
            {
                UserId = 1
            };

            var updates = new Dictionary<object, Restrictions.ShadowModifiedMember[]>();
            updates[attr] = new Restrictions.ShadowModifiedMember[]
                {
                    new Restrictions.ShadowModifiedMember
                    {
                        Member = typeof(UserAttribute).GetProperty("UserId"),
                        CurrentValue = attr.Id,
                        OriginalValue = 2
                    }
                };

            string ignored;
            Assert.IsTrue(r.IsValidChangeSet(updates, new List<object>(), new List<object>(), new List<object>() { attr }, new List<int>() { 1 }, out ignored));
        }