Example #1
0
        public void SetFormChangeSet <TForm>([CanBeNull] FormChangeSet <TForm> changeSet)
        {
            if (changeSet == null)
            {
                FormChangeSetSerialized = null;
                return;
            }

            using (var memoryStream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(memoryStream, changeSet);
                FormChangeSetSerialized = memoryStream.ToArray();
            }
        }
Example #2
0
        public ActionResult EventLog(int id)
        {
            Election election = db.Elections.Find(id);

            if (election == null)
            {
                return(HttpNotFound());
            }

            List <EventLogEntry> entries = new List <EventLogEntry>();

            entries.AddRange(
                db.AdminActionRecords
                .Where(record => record.ElectionId == election.Id)
                .AsEnumerable()
                .Select(record =>
            {
                EventLogEntry entry = new EventLogEntry
                {
                    User      = record.UserId,
                    OccuredAt = record.OccurredAt,
                };

                switch (record.Type)
                {
                case AdminActionRecord.RecordType.ViewVotes:
                    entry.Text = "Viewed votes";
                    break;

                case AdminActionRecord.RecordType.Edit:
                    FormChangeSet <ElectionForm> changeSet =
                        record.GetChangeSet <ElectionForm>();
                    Debug.Assert(changeSet != null, nameof(changeSet) + " != null");

                    entry.Text = "Edited election properties. Changed fields:"
                                 + FormChangeSetPrinter.GenerateHtmlList(changeSet.Delta);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return(entry);
            })
                );

            entries.AddRange(
                db.ElectionStateChanges
                .Where(change => change.ElectionId == election.Id && change.CompletedAt != null)
                .AsEnumerable()
                .Select(change => new EventLogEntry
            {
                // ReSharper disable once PossibleInvalidOperationException
                OccuredAt = (DateTime)change.CompletedAt,
                User      = change.InstigatorUsername,
                Text      = change.PreviousState.HasValue
                            ? "State changed from " + change.PreviousState.ToString() + " to " +
                            change.TargetState.ToString()
                            : "Election created"
            })
                );

            IDictionary <string, TimetableUserEntry> users = GetTimetableUsers(
                entries.Select(data => data.User).Where(userid => !string.IsNullOrEmpty(userid))
                );

            foreach (EventLogEntry entry in entries)
            {
                if (entry.User != null && users.TryGetValue(entry.User, out TimetableUserEntry userEntry))
                {
                    entry.User = userEntry.Fullname;
                }
            }

            return(View(new EventLogData
            {
                Election = election,
                Entries = entries.OrderByDescending(entry => entry.OccuredAt).ToArray()
            }));
        }
Example #3
0
        public ActionResult Edit(int id)
        {
            Election election = db.Elections.Find(id);

            if (election == null)
            {
                return(HttpNotFound());
            }

            CouncilElectionData councilData = null;
            CouncilElectionForm councilForm = null;
            ElectionForm        form;

            if (election.Type == ElectionType.StudentCouncil)
            {
                councilData = db.CouncilElectionData.First(data => data.ElectionId == election.Id);
                form        = councilForm = GenerateFormForCouncil(election, councilData);
            }
            else
            {
                form = GenerateFormForCourseRep(election);
            }

            ModelFieldsAccessibility fieldsInfo = ElectionLifecycleInfo.GetWhatCanBeEditedCouncil(election);

            ViewData[FormConstants.FieldsInfoKey] = fieldsInfo;
            ViewBag.Election = election;

            fieldsInfo.EnsureAllowedDefaultKind(
                ModelFieldsAccessibility.Kind.Editable,
                nameof(AdminElectionsController) + "." + nameof(Edit)
                );

            if (Request.HttpMethod.ToUpper() != "POST")
            {
                // Just show the template
                return(View("Edit", form));
            }

            AntiForgery.Validate();

            // Update the form based on data that we received
            // ReSharper disable once ConvertIfStatementToNullCoalescingExpression - we need the compiler to specify different generic arguments
            if (councilForm != null)
            {
                TryUpdateModel(councilForm);
            }
            else
            {
                TryUpdateModel(form);
            }

            // Get the original form so that we use old values for uneditable fields
            CouncilElectionForm councilOriginalForm = null;
            ElectionForm        originalForm;

            if (councilForm != null)
            {
                originalForm = councilOriginalForm = GenerateFormForCouncil(election, councilData);
            }
            else
            {
                originalForm = GenerateFormForCourseRep(election);
            }

            // Replace all uneditable values with old ones
            fieldsInfo.ReplaceUneditableWithOldValues(form, originalForm);

            // As the role IDs are sent from user, we need to make sure that they weren't changed
            if (councilForm != null && fieldsInfo.CanBeChangedByUser(nameof(CouncilElectionForm.Roles)))
            {
                IEnumerable <int?> initialRoleIds = councilOriginalForm.Roles.Select(role => role.Id);
                IEnumerable <int?> newRoleIds     = councilForm.Roles.Select(role => role.Id);

                if (!initialRoleIds.SequenceEqual(newRoleIds))
                {
                    throw new Exception("The IDs of roles were changed by user input");
                }
            }

            // Validate again (since some rules are relative to other fields and can be affected by operations above)
            TryValidateModel(form);

            // Ignore the failures from uneditable fields
            this.RemoveIgnoredErrors(fieldsInfo);

            if (!ModelState.IsValid)
            {
                // The validation failed so we just display the form again
                return(View("Edit", form));
            }

            // Record the admin action
            AdminActionRecord actionRecord = CreateActionRecord(election, AdminActionRecord.RecordType.Edit);

            actionRecord.SetFormChangeSet(FormChangeSet.Generate(form, originalForm));
            db.AdminActionRecords.Add(actionRecord);

            // Validation passed with the fields that are allowed to change. Persist the changes
            Mapper.Map(form, election);
            if (councilData != null)
            {
                Mapper.Map(form, councilData);
            }

            db.SaveChanges();

            BackgroundJob.Enqueue <SynchronizeDelayedJobsJob>(job => job.Execute(election.Id));
            AuditLogManager.RecordElectionEdit(User, election);

            return(RedirectToAction("Details", new { id }));
        }