Skip to content

Commit

Permalink
Merge pull request #9 from AY2324S1-CS2103T-T12-4/master
Browse files Browse the repository at this point in the history
Pull recent changes
  • Loading branch information
adammangzijun authored Nov 9, 2023
2 parents a759754 + 6a81cad commit a15cd88
Show file tree
Hide file tree
Showing 46 changed files with 432 additions and 307 deletions.
43 changes: 1 addition & 42 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ pageNav: 3
# MedBook Developer Guide
## Acknowledgements

This project has benefited from the use of several third-party libraries, as well as ideas and code snippets from various sources. We express our gratitude to the creators and maintainers of these resources.

### Java Cryptography Extension (JCE)

The project utilizes the Java Cryptography Extension (JCE) for implementing encryption and decryption functionalities. Specific classes such as `Cipher`, `IvParameterSpec`, and `SecretKeySpec` have been used to perform cryptographic operations.

- `javax.crypto.Cipher`: This class provides the functionality of a cryptographic cipher, used here for encryption and decryption.
- `javax.crypto.spec.IvParameterSpec`: This class specifies an initialization vector (IV) to provide an additional parameter to algorithms.
- `javax.crypto.spec.SecretKeySpec`: This class specifies a secret key in a provider-independent fashion.

These classes are part of the Java Cryptography Extension (JCE) framework, which is included in the Java Standard Edition (Java SE) from Oracle. More information can be found on the [Official Oracle Documentation](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/crypto/Cipher.html).

We ensure that all used and redistributed libraries are credited appropriately, and we encourage users and developers to also adhere to the terms and conditions of each library's license.
This project has not used any third-party libraries.

---

Expand Down Expand Up @@ -315,35 +303,6 @@ The following sequence diagram shows how the view operation works:

---

## Encryption/Decryption Feature

### Implementation

MedBook secures user data through automatic encryption before saving to disk and decryption upon loading.

#### How it Works

1. **Encryption**: Upon executing a data-altering command:
- Convert data object to JSON.
- Encrypt the JSON string using AES (CBC mode, PKCS5 padding).
- Save encrypted string to disk.
2. **Decryption**: Upon application start:
- Read and decrypt the stored string.
- Convert the decrypted JSON back into a data object.

### Design Considerations

#### Choice of Encryption Algorithm

- **Alternative 1**: (Chosen) Use AES in CBC mode with PKCS5 padding.
- _Pros_: Strong, trusted encryption.
- _Cons_: Potentially high computational cost for large datasets.
- **Alternative 2**: Use a lighter encryption algorithm.
- _Pros_: Faster processing times.
- _Cons_: Potentially less secure.

---

## Attach Files to Patient Records

### Implementation Details
Expand Down
110 changes: 63 additions & 47 deletions docs/UserGuide.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorials/AddRemark.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ save it with `Model#setPerson()`.
List<Person> lastShownList = model.getFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX + ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person personToEdit = lastShownList.get(index.getZeroBased());
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package seedu.address.logic;

import java.nio.file.Path;
import java.util.List;

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
Expand Down Expand Up @@ -63,4 +65,6 @@ public interface Logic {
ObservableList<Record> getRecordList();

ObservableList<Person> getPersonBeingViewed();

List<Index> getPatientIndex();
}
6 changes: 6 additions & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.Path;
import java.util.List;
import java.util.logging.Logger;

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
Expand Down Expand Up @@ -98,6 +100,10 @@ public ObservableList<Person> getPersonBeingViewed() {
return model.getPersonBeingViewed();
}

public List<Index> getPatientIndex() {
return model.getPatientIndex();
}

@Override
public Path getAddressBookFilePath() {
return model.getAddressBookFilePath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person patient = lastShownList.get(index.getZeroBased());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class AddCommand extends Command {


public static final String MESSAGE_SUCCESS = "New person added: %1$s";
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the Medbook";

private final Person toAdd;

Expand Down
11 changes: 9 additions & 2 deletions src/main/java/seedu/address/logic/commands/AddRecordCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class AddRecordCommand extends Command {

public static final String MESSAGE_SUCCESS = "New record added: %1$s";

public static final String MESSAGE_DUPLICATE_RECORDS = "This record already exists in the record of the patient.";

private final Record record;

private final Index index;
Expand All @@ -54,7 +56,12 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

if (model.hasRecord(record, index)) {
throw new CommandException(MESSAGE_DUPLICATE_RECORDS);
}

Person personToAddRecord = lastShownList.get(index.getZeroBased());
Expand All @@ -67,7 +74,7 @@ public CommandResult execute(Model model) throws CommandException {
newRecords, personToAddRecord.getAppointments(), personToAddRecord.isPinned());

model.setPerson(personToAddRecord, personWithAddedRecord);
model.updateRecordList(personWithAddedRecord);
model.updateRecordList(personWithAddedRecord, index);

return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(record, personWithAddedRecord)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person personToDelete = lastShownList.get(targetIndex.getZeroBased());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (targetPatientIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}
Person targetPatient = lastShownList.get(targetPatientIndex.getZeroBased());
UniqueRecordList newRecordsList = new UniqueRecordList();
Expand All @@ -58,7 +59,7 @@ public CommandResult execute(Model model) throws CommandException {
targetPatient.getBloodType(), targetPatient.getAllergies(), newRecordsList,
targetPatient.getAppointments(), targetPatient.isPinned());
model.setPerson(targetPatient, patientWithDeletedRecord);
model.updateRecordList(patientWithDeletedRecord);
model.updateRecordList(patientWithDeletedRecord, targetPatientIndex);
return new CommandResult(String.format(MESSAGE_DELETE_RECORD_SUCCESS,
Messages.format(targetRecord, targetPatient)));
}
Expand Down
8 changes: 5 additions & 3 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ public class EditCommand extends Command {

/**
* @param index
* of the person in the filtered person list to edit
* of the person in the filtered person list to edit
* @param editPersonDescriptor
* details to edit the person with
* details to edit the person with
*/
public EditCommand(Index index, EditPersonDescriptor editPersonDescriptor) {
requireNonNull(index);
Expand All @@ -84,7 +84,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (index.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person personToEdit = lastShownList.get(index.getZeroBased());
Expand All @@ -96,6 +97,7 @@ public CommandResult execute(Model model) throws CommandException {

model.setPerson(personToEdit, editedPerson);
model.updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
model.updateRecordList(editedPerson, index);
return new CommandResult(String.format(MESSAGE_EDIT_PERSON_SUCCESS,
Messages.format(editedPerson)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownPersonList = model.getFilteredPersonList();

if (patientIndex.getZeroBased() >= lastShownPersonList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownPersonList.size() + ".");
}

Person personToEdit = lastShownPersonList.get(patientIndex.getZeroBased());
Expand All @@ -89,7 +90,8 @@ public CommandResult execute(Model model) throws CommandException {
Record recordToEdit = lastShownRecordList.get(recordIndex.getZeroBased());
Record editedRecord = createEditedRecord(recordToEdit, editRecordDescriptor);

if (recordToEdit.equals(editedRecord) && uniqueRecordList.contains(editedRecord)) {

if (recordToEdit.equals(editedRecord) || uniqueRecordList.contains(editedRecord)) {
throw new CommandException(MESSAGE_DUPLICATE_RECORD);
}

Expand All @@ -103,7 +105,7 @@ public CommandResult execute(Model model) throws CommandException {
}

model.setPerson(personToEdit, editedPerson);
model.updateRecordList(editedPerson);
model.updateRecordList(editedPerson, this.patientIndex);
return new CommandResult(String.format(MESSAGE_EDIT_RECORD_SUCCESS,
Messages.format(editedRecord, personToEdit)));
}
Expand Down Expand Up @@ -270,7 +272,7 @@ public boolean equals(Object other) {
}

EditRecordCommand.EditRecordDescriptor otherEditRecordDescriptor =
(EditRecordCommand.EditRecordDescriptor) other;
(EditRecordCommand.EditRecordDescriptor) other;
return Objects.equals(dateTime, otherEditRecordDescriptor.dateTime)
&& Objects.equals(conditions, otherEditRecordDescriptor.conditions)
&& Objects.equals(filePath, otherEditRecordDescriptor.filePath)
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/commands/PinCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person personToPin = lastShownList.get(targetIndex.getZeroBased());
Expand Down Expand Up @@ -71,4 +72,3 @@ public String toString() {
.toString();
}
}

7 changes: 4 additions & 3 deletions src/main/java/seedu/address/logic/commands/UnpinCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
import seedu.address.model.person.Person;

/**
* Unpins the person identified using it's displayed index from the address book.
* Unpins the person identified using it's displayed index from the address
* book.
*/
public class UnpinCommand extends Command {

Expand All @@ -37,7 +38,8 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownPinnedList = model.getPinnedPersonList();

if (targetIndex.getZeroBased() >= lastShownPinnedList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownPinnedList.size() + ".");
}

Person personToUnpin = lastShownPinnedList.get(targetIndex.getZeroBased());
Expand Down Expand Up @@ -72,4 +74,3 @@ public String toString() {
.toString();
}
}

12 changes: 7 additions & 5 deletions src/main/java/seedu/address/logic/commands/ViewCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ public class ViewCommand extends Command {
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";

public static final String MESSAGE_VIEW_PERSON_SUCCESS = "View Person: %1$s";
public static final String MESSAGE_VIEW_PERSON_SUCCESS = "View Patient: %1$s";

private final Index targetIndex;

/**
* Constructor for ViewCommand class
*
* @param targetIndex the patient Index to view
*/
public ViewCommand(Index targetIndex) {
Expand All @@ -44,12 +45,13 @@ public CommandResult execute(Model model) throws CommandException {
List<Person> lastShownList = model.getFilteredPersonList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX
+ ". Please ensure that it is within 1 and " + lastShownList.size() + ".");
}

Person personToView = lastShownList.get(targetIndex.getZeroBased());
model.updateRecordList(personToView);
return new CommandResult(String.format(MESSAGE_VIEW_PERSON_SUCCESS, Messages.format(personToView)));
Person patientToView = lastShownList.get(targetIndex.getZeroBased());
model.updateRecordList(patientToView, targetIndex);
return new CommandResult(String.format(MESSAGE_VIEW_PERSON_SUCCESS, Messages.format(patientToView)));
}

@Override
Expand Down
20 changes: 19 additions & 1 deletion src/main/java/seedu/address/model/AddressBook.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package seedu.address.model;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.util.ArrayList;
import java.util.List;

import javafx.collections.ObservableList;
import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.appointment.Appointment;
import seedu.address.model.appointment.UniqueAppointmentList;
Expand All @@ -24,6 +26,7 @@ public class AddressBook implements ReadOnlyAddressBook {
private final UniquePersonList personBeingViewed;
private final UniqueRecordList records;
private final UniqueAppointmentList appointments;
private List<Index> patientIndex;
/*
* The 'unusual' code block below is a non-static initialization block,
* sometimes used to avoid duplication
Expand All @@ -39,6 +42,7 @@ public class AddressBook implements ReadOnlyAddressBook {
records = new UniqueRecordList();
appointments = new UniqueAppointmentList();
personBeingViewed = new UniquePersonList();
patientIndex = new ArrayList<>();
}

public AddressBook() {
Expand All @@ -62,9 +66,11 @@ public void setPersons(List<Person> persons) {
this.persons.setPersons(persons);
}

public void setRecords(Person person) {
public void setRecords(Person person, Index index) {
ArrayList<Person> beingViewed = new ArrayList<>();
beingViewed.add(person);
this.patientIndex.clear();
this.patientIndex.add(index);
this.personBeingViewed.setPersons(beingViewed);
this.records.setRecords(person.getRecords());
}
Expand All @@ -90,6 +96,14 @@ public boolean hasPerson(Person person) {
return persons.contains(person);
}

/**
* Returns true if the same record under the patient at {@code index} exists in the Medbook.
*/
public boolean hasRecord(Record record, Index index) {
requireAllNonNull(record, index);
return persons.asUnmodifiableObservableList().get(index.getZeroBased()).getRecords().contains(record);
}

/**
* Adds a person to the address book.
* The person must not already exist in the address book.
Expand Down Expand Up @@ -137,6 +151,10 @@ public ObservableList<Record> getRecordList() {
return records.asUnmodifiableObservableList();
}

public List<Index> getPatientIndex() {
return this.patientIndex;
}

public ObservableList<Appointment> getAppointmentList() {
resetAppointmentList();
return appointments.asUnmodifiableObservableList();
Expand Down
Loading

0 comments on commit a15cd88

Please sign in to comment.