Пример #1
0
        public void PurgeClient(ClientRecord clientRecord)
        {
            if (!this.Connected)
                throw new InvalidOperationException("Cannot purge the client because the database is not connected.");
            if (!this.Authenticated)
                throw new InvalidOperationException("Cannot purge the client because the current user is not authenticated with the Database.");
            if (clientRecord == null)
                throw new ArgumentNullException("clientRecord");

            int id;
            if (!_clients.TryGetKey(clientRecord, out id))
                throw new ArgumentException("Cannot purge this client because it does not exist in this database.");

            //delete entries and associated values (takes care of both memory and DB)
            clientRecord.RemoveEntries(clientRecord.Entries.ToList());
            CommitClient(clientRecord);

            //delete client in DB
            var purgeCommand = new SqlCommand("sp_PurgeClient", _connection) { CommandType = System.Data.CommandType.StoredProcedure };
            purgeCommand.Parameters.Add(new SqlParameter("token", "null_token"));    //TODO: token will go here
            purgeCommand.Parameters.Add(new SqlParameter("client_id", id));
            purgeCommand.ExecuteNonQuery();

            //delete client in memory
            _clients.Remove(clientRecord);

            OnClientsRemoved(new ClientRecordEventArgs(clientRecord));

            AddLogEntryInternal(UserLogEntryType.Delete, null, String.Format("Purged client: {0}", clientRecord.Name));
        }
Пример #2
0
        /// <summary>
        /// Populates a ClientRecord's Security and ClientEntries list from the database.
        /// </summary>
        /// <param name="client"></param>
        /// <remarks>
        ///     This method is horrifically long and is due for refactoring.
        /// </remarks>
        public void Refresh(ClientRecord client)
        {
            //preconditions
            if (!this.Connected)
                throw new InvalidOperationException("Cannot get the list of entries for this client because the database is not connected.");
            if (!this.Authenticated)
                throw new InvalidOperationException("Cannot get the list of entries for this client because the current user is not authenticated with the Database.");

            RefreshDefaultSecurity();
            RefreshClientSecurityInternal(client);

            if ((client.Security.Count == 0 && this.DefaultSecurity.CheckIsAllowedView(this.CurrentUser)) ||
                client.Security.CheckIsAllowedView(this.CurrentUser))
            {
                RefreshClientEntriesInternal(client);
            }
            else
            {
                client.RemoveEntries(client.Entries);
            }
        }
Пример #3
0
        private void RefreshClientEntriesInternal(ClientRecord client)
        {
            //preparation
            int clientId = _clients[client];
            if (!_clients.TryGetKey(client, out clientId))
                throw new ArgumentException("The specified client is not in this database.");

            var newEntries = new List<ClientEntry>();
            var prevEntryIds = client.Entries.Select(e => _entries[e]).ToList();

            //Query the Database
            var getListCommand = new SqlCommand("sp_GetClientEntries", _connection) { CommandType = System.Data.CommandType.StoredProcedure };
            getListCommand.Parameters.Add(new SqlParameter("token", "null_token"));    //TODO: token will go here
            getListCommand.Parameters.Add(new SqlParameter("client_id", clientId));

            using (var reader = getListCommand.ExecuteReader())
            {
                //result set 1: entry list for the specified client
                while (reader.Read())
                {
                    ClientEntry entry;
                    int clientEntryDbId = (int)reader[0];

                    //index the entry if it is new
                    if (!_entries.TryGetItem(clientEntryDbId, out entry))
                    {
                        entry = new ClientEntry();
                        _entries.Add(clientEntryDbId, entry);
                        newEntries.Add(entry);
                    }

                    //update the properties of the entry, regardless if it existed before
                    entry.Name = (string)reader[2];
                    entry.IconIndex = (int)reader[3];
                    entry.Notes = WebUtility.HtmlDecode((reader[5] as string ?? String.Empty).Replace("<br>", Environment.NewLine));

                    //set the template, it will get updated later if it doesn't exist yet
                    //we index the new template right away
                    EntryTemplate template;
                    int templateId = (reader[4] == DBNull.Value) ? -1 : (int)reader[4];
                    if (templateId == -1)
                    {
                        template = null;    //orphaned record
                    }
                    else if (!_templates.TryGetItem(templateId, out template))
                    {
                        template = new EntryTemplate();
                        _templates.Add(templateId, template);
                    }
                    entry.Template = template;
                }

                //result set 2: template definition
                reader.NextResult();
                while (reader.Read())
                {
                    EntryTemplate template;
                    int templateDbId = (int)reader[0];

                    if (!_templates.TryGetItem(templateDbId, out template))
                        throw new InvalidOperationException("A template was returned that was not part of the first result set.");

                    //update the properties
                    template.Name = reader[1] as string;
                    template.IconIndex = (int)reader[2];
                    template.AllowCustomFields = (bool)reader[3];
                }

                //result set 3: fields for the previous templates
                reader.NextResult();
                while (reader.Read())
                {
                    EntryField templateField;
                    EntryTemplate template;
                    int templateFieldId = (int)reader[0];
                    int templateId = (int)reader[1];
                    if (!_templates.TryGetItem(templateId, out template))
                        throw new InvalidOperationException("A template field was returned that belongs to a template that was not returned in the previous result set.");

                    if (!_templateFields.TryGetItem(templateFieldId, out templateField))
                    {
                        templateField = new EntryField();
                        _templateFields.Add(templateFieldId, templateField);
                    }

                    if (!template.Fields.Contains(templateField))
                        template.AddField(templateField);

                    //update the properties
                    templateField.Name = reader[2] as string;
                    templateField.EntryType = (EntryFieldType)reader[3];
                    templateField.DefaultValue = reader[4] as string;
                }
                //TODO: remove any fields that were not returned

                //result set 4: field values
                reader.NextResult();
                while (reader.Read())
                {
                    int fieldValueId = (int)reader[0];
                    int entryId = (int)reader[1];

                    ClientEntry entry;
                    if (!_entries.TryGetItem(entryId, out entry))
                        throw new InvalidOperationException("A ClientEntry was returned that was not defined in a previous result set.");

                    int templateFieldId = (reader[2] == DBNull.Value) ? -1 : (int)reader[2];
                    string entryValue = reader[4] as string;

                    //indexing of fields values:
                    //  template field values are indexed by TFVR objects in the _templateFieldsById dictionary
                    //  custom field values are indexed by just the EntryField object in the _customFieldsById dictionary
                    if (templateFieldId == -1)
                    {
                        //custom field
                        string fieldName = reader[3] as string;
                        EntryField customField;
                        if (!_customFields.TryGetItem(fieldValueId, out customField))
                        {
                            customField = new EntryField() { Name = fieldName };    //todo: type
                            entry.AddCustomField(customField);
                            _customFields.Add(fieldValueId, customField);
                        }

                        //update the name and value
                        customField.Name = fieldName;
                        entry.SetValue(customField, DataSecurity.DecryptStringAES(entryValue));
                    }
                    else
                    {
                        //find the template EntryField by ID
                        EntryField templateField;
                        if (_templateFields.TryGetItem(templateFieldId, out templateField))
                        {
                            //save the ID of the field value for saving later
                            if (!_templateValues.Values.Any(tfvr => tfvr.ClientEntry == entry && tfvr.TemplateField == templateField))
                                _templateValues.Add(fieldValueId, new TemplateFieldValueRelation() { ClientEntry = entry, TemplateField = templateField });

                            entry.SetValue(templateField, DataSecurity.DecryptStringAES(entryValue));
                        }
                        else
                        {
                            throw new InvalidOperationException("A template field was returned that cannot be matched to an existing template.");
                        }
                    }
                }
                //TODO: remove any fields that were not returned
            }

            //clean up the internal list, and raise events for the UI
            var deletedEntryIds = prevEntryIds.Except(_entries.Keys).ToList();
            if (deletedEntryIds.Any())
            {
                var deletedEntries = new List<ClientEntry>();
                foreach (var id in deletedEntryIds)
                {
                    var entry = _entries[id];
                    deletedEntries.Add(entry);
                    _entries.Remove(entry);
                }

                client.RemoveEntries(deletedEntries);
            }

            if (newEntries.Any())
                client.AddEntries(newEntries);
        }