architecture.md 4.16 KB
Newer Older
Florent Chehab's avatar
Florent Chehab committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
# Application architecture

This is a short introduction to the architecture used for this application.

## Simplified schema
Here is a simplified schema of the application structure (mainly concerning the database) :

![UML of the application](../data/images/schema.png)



## Anonymous

So users can be anonymous when they answer a form.

The logic behind it is quite simple : because a user should be able to answer a form only once, **we need to store the data about the fact that he/she has answered a form**. The *anonymous* characteristic will take place when creating a link between knowing that a user has answered a form and what is exactly his/her form submission. Therefore, when answereing as an *anonymous user*, the `formSubmissionId` **is not stored** in the `formSubitted` table ! To enable editing of anonymous form submissions, the `uid` of the form submission is given to the user, so that he/she is the only one that can access it again.

 - For this to work safely, a **secure** client/server connection should be used.

  *About the cool feature of PGP encryption, the encryption is done entirely on the server, only using PHP.*


Conclusion : in the *anonymous case* **It is possible to know if a user has answered a form**. If there has only been one answer to a form the user is only *virtually* anonymous. Otherwise, the user is *technically* anonymous !


## Talk about security

**Making the app as secure as possible has been a big challenge.**
- Besides tradionnal SQL checks to see if a user can do what he/she is about to do, the security relies heavily on the `session` system by setting temporary *checkpoints* forcing the user to have passed the previous *checkoint(s)* or preventing the user from going back to a previous *checkpoint*.

- None of the apps interface (**ajax included**) should *talk* to an unauthorized person. So, for example, throwing a random ajax request will get you nowhere.

- Concerning ajax :
 - the user has to be logged-in for any interactions to take place and there systematic checks before sending data back to the user.
 - A token system is used so the system cannot answer unlimited *requests*.


## Form valiation
This comes right after security, because the app relies on exactly the same form system as the one the user can use. **So it must be robust...**
- There is of course a client side validation of the form-submissions.
- There is also a server side validation of the form-submissions (**using only data on the server**). This validation will take into account all the constraint available to the user and the *coherence* of their answers (was this answer possible).

**There is also a server side validation for the form created by the users. To make sure only authorized fields are used... and that they are well used.**

This validation enables an *expert mode* for form creation : you can create form element (or entire form) 100% through JSON. *This should be usefull when dealing with a lot of options in a select for example.*



## A small description of the `Answer` controller

Because the structure of this controller might be a little bit complicated to understand, here is a summury :

- To answer a form, the function `form` is used as a switch : if the user has already answered the form he/she is redirected to the `getAccess` function directly. If he/she hasn't answered the form yet, he/she is redirected to the `init` function.

 - The `init` function is there to get the user approval on what info is associatted to his/her form submission.
 - On success the user is redirected to the `getAccess` function with some cached data so that `getAccess` will redirect the user directly to `edit` function.


- (Otherwise) the `getAccess` function will check if the form submission for this form (and this user) was anonymous, if not we have access to the `submissionId` directly in the database. Otherwise, we have to retreive it.

	- So if the user was anonymous, he/she is redirected to the function `anonymousAccess` where he/she is able to type the `uid` he/she was given. If the `uid` is valid (for the `formid`), the original submissionId is retreived from the database, and he/she goes back to the `getAccess` function and then directly to the `edit` function.