@ -1533,36 +1533,38 @@ more convenient, but provides us with less control.
#### Authentication
#### Authentication
To make certain data and actions acessible only for some specific users, there
To make certain data and actions acessible only for some specific users, there
must be a way how these users can prove their identity. We decided to avoid
must be a way how these users can prove their identity. We decided to avoid PHP
PHP sessions to make the server stateless (session ID is stored in the cookies
sessions to make the server stateless (session ID is stored in the cookies of
of the HTTP requests and responses). The server issues a specific token for the
the HTTP requests and responses). The server issues a specific token for the
user after his/her identity is verified (i.e., by providing email and password)
user after his/her identity is verified (i.e., by providing email and password)
and sent to the client in the body of the HTTP response. The client must remember
and sent to the client in the body of the HTTP response. The client must
this token and attach it to every following request in the *Authorization* header.
remember this token and attach it to every following request in the
*Authorization* header.
The token must be valid only for a certain time period ("log out" the user after
The token must be valid only for a certain time period ("log out" the user after
a few hours of inactivity) and it must be protected against abuse (e.g., an attacker
a few hours of inactivity) and it must be protected against abuse (e.g., an
must not be able to issue a token which will be considered valid by the system and
attacker must not be able to issue a token which will be considered valid by the
using which the attacker could pretend to be a different user). We decided to use
system and using which the attacker could pretend to be a different user). We
the JWT standard (the JWS).
decided to use the JWT standard (the JWS).
The JWT is a base64-encoded string which contains three JSON documents - a header,
The JWT is a base64-encoded string which contains three JSON documents - a
some payload, and a signature. The interesting parts are the payload and the signature:
header, some payload, and a signature. The interesting parts are the payload and
the payload can contain any data which can identify the user and metadata of the token
the signature: the payload can contain any data which can identify the user and
(i.e., the time when the token was issued, the time of expiration). The last part is a
metadata of the token (i.e., the time when the token was issued, the time of
digital signature contains a digital signature of the header and payload and it
expiration). The last part is a digital signature contains a digital signature
ensures that nobody can issue their own token and steal someone's identity. Both of
of the header and payload and it ensures that nobody can issue their own token
these characteristics give us the opportunity to validate the token without storing
and steal someone's identity. Both of these characteristics give us the
all of the tokens in the database.
opportunity to validate the token without storing all of the tokens in the
database.
To implement JWT in Nette, we have to implement some of its security-related
To implement JWT in Nette, we have to implement some of its security-related
interfaces such as IAuthenticator and IUserStorage, which is rather easy
interfaces such as IAuthenticator and IUserStorage, which is rather easy thanks
thanks to the simple authentication flow. Replacing these services in a Nette
to the simple authentication flow. Replacing these services in a Nette
application is also straightforward, thanks to its dependency injection
application is also straightforward, thanks to its dependency injection
container implementation. The encoding and decoding of the tokens itself
container implementation. The encoding and decoding of the tokens itself
including generating the signature and signature verification is done through
including generating the signature and signature verification is done through a
a widely used third-party library which lowers the risk of having a bug
widely used third-party library which lowers the risk of having a bug in the
in the implementation of this critical security feature.
implementation of this critical security feature.
#### Uploading files
#### Uploading files
@ -1624,10 +1626,10 @@ We decided for the lazy loading at the time when the results are requested for
the first time. However, the concept of asynchronous jobs is then introduced.
the first time. However, the concept of asynchronous jobs is then introduced.
This type of job is useful for batch submitting of jobs, for example re-running
This type of job is useful for batch submitting of jobs, for example re-running
jobs which failed on a worker hardware issue. These jobs are typically submitted
jobs which failed on a worker hardware issue. These jobs are typically submitted
by different user than the author (an administrator for example), so the original
by different user than the author (an administrator for example), so the
authors should be notified. In this case it is more reasonable to load the results
original authors should be notified. In this case it is more reasonable to load
immediately and optionally send them a notification via an email. This is exactely
the results immediately and optionally send them a notification via an email.
what we do.
This is exactely what we do.
It seems with the benefit of hindsight that immediate loading of all jobs could
It seems with the benefit of hindsight that immediate loading of all jobs could
simplify the code and it has no major drawbacks. In the next version of ReCodEx
simplify the code and it has no major drawbacks. In the next version of ReCodEx
@ -1637,21 +1639,46 @@ we will re-evaluate this decision.
##### Backend failiure reporting
##### Backend failiure reporting
The backend is a separate component which does not communicate with the administrators directly. When it encounters an error it stores it in a log file. It would be handy to inform the administrator directly at this moment so he can fix the cause of the error as soon as possible. The backend does not have any mechanism for notifying users using for example an email. The API server on the other hand has email sending implemented and it can easily forward any messages to the administrator. A secured communication protocol between the backend and the frontend already exists (it is used for the reporting of a finished job processing) and it is easy to add another endpoint for bug reporting.
The backend is a separate component which does not communicate with the
administrators directly. When it encounters an error it stores it in a log file.
When a request for sending a report arrives from the backend then the type of the report is inferred and if it is an error which deserves attention of
It would be handy to inform the administrator directly at this moment so he can
the administrator then an email is sent to him/her. There can also be errors which are not that important (e.g., it was somehow solved by the backend itself or it is only informative, then these do not have to be reported through an email but can only be stored in the persistent database for further consideration.
fix the cause of the error as soon as possible. The backend does not have any
mechanism for notifying users using for example an email. The API server on the
On top of that the separate backend component does not have to be exposed to the outside network at all.
other hand has email sending implemented and it can easily forward any messages
to the administrator. A secured communication protocol between the backend and
If a job processing fails then the backend informs the API server which initiated processing of the job. If an error which is not related to job-processing occurs then the backend must communicate with a given API server which is configured by the administrator while the other API servers which are using the same backend are not informed.
the frontend already exists (it is used for the reporting of a finished job
processing) and it is easy to add another endpoint for bug reporting.
When a request for sending a report arrives from the backend then the type of
the report is inferred and if it is an error which deserves attention of the
administrator then an email is sent to him/her. There can also be errors which
are not that important (e.g., it was somehow solved by the backend itself or it
is only informative, then these do not have to be reported through an email but
can only be stored in the persistent database for further consideration.
On top of that the separate backend component does not have to be exposed to the
outside network at all.
If a job processing fails then the backend informs the API server which
initiated processing of the job. If an error which is not related to
job-processing occurs then the backend must communicate with a given API server
which is configured by the administrator while the other API servers which are
using the same backend are not informed.
##### Backend state monitoring
##### Backend state monitoring
The next thing related to communication with the backend is monitoring its current state. This concerns namely which workers are available for processing different hardware groups and which languages can be therefore used in exercises.
The next thing related to communication with the backend is monitoring its
current state. This concerns namely which workers are available for processing
different hardware groups and which languages can be therefore used in
exercises.
Another step would be the overall backend state like how many jobs were processed by some particular worker, workload of the broker and the workers, etc. The easiest solution is to manage this information by hand, every
Another step would be the overall backend state like how many jobs were
instance of the API server has to have an administrator which would have to fill them. This of course includes only the currently available workers and runtime environments which does not change very often. The real-time statistics of the backend cannot be made accesible this way in a reasonable way.
processed by some particular worker, workload of the broker and the workers,
etc. The easiest solution is to manage this information by hand, every instance
of the API server has to have an administrator which would have to fill them.
This of course includes only the currently available workers and runtime
environments which does not change very often. The real-time statistics of the
backend cannot be made accesible this way in a reasonable way.
A better solution is to update this information automatically. This can be
A better solution is to update this information automatically. This can be
done in two ways:
done in two ways:
@ -1659,9 +1686,13 @@ done in two ways:
- It can be provided by the backend on-demand if API needs it
- It can be provided by the backend on-demand if API needs it
- The backend will send these information periodically to the API.
- The backend will send these information periodically to the API.
Things like currently available workers or runtime environments are better to be really up-to-date so this could be provided on-demand if needed. Backend statistics are not that necessary and could be updated periodically.
Things like currently available workers or runtime environments are better to be
really up-to-date so this could be provided on-demand if needed. Backend
statistics are not that necessary and could be updated periodically.
However due to the lack of time automatic monitoring of the backend state will not be implemented in the early versions of this project but might be implemented in some of the next releases.
However due to the lack of time automatic monitoring of the backend state will
not be implemented in the early versions of this project but might be
implemented in some of the next releases.
### Web-app
### Web-app
@ -1683,38 +1714,39 @@ for implementation of a website.
There are two basic ways how to create a website these days:
There are two basic ways how to create a website these days:
- **server-side approach** - user's actions are processed on the server and the
- **server-side approach** - user's actions are processed on the server and the
HTML code with the results of the action is generated on the server and sent back
HTML code with the results of the action is generated on the server and sent
to the user's Internet browser. The client does not handle any logic (apart from
back to the user's Internet browser. The client does not handle any logic
rendering of the user interface and some basic user interaction) and is therefore
(apart from rendering of the user interface and some basic user interaction)
very simple. The server can use the API server for processing of the actions so
and is therefore very simple. The server can use the API server for processing
the business logic of the server can be very simple as well. A disadvantage of
of the actions so the business logic of the server can be very simple as well.
this approach is that a lot of redundant data is transferred across the requests
A disadvantage of this approach is that a lot of redundant data is transferred
although some parts of the content can be cached (e.g., CSS files). This results
across the requests although some parts of the content can be cached (e.g.,
in longer loading times of the website.
CSS files). This results in longer loading times of the website.
- **server-side rendering with asynchronous updates (AJAX)** - a slightly different
- **server-side rendering with asynchronous updates (AJAX)** - a slightly
approach is to render the page on the server as in the previous case but then
different approach is to render the page on the server as in the previous case
execute user's actions asynchronously using the `XMLHttpRequest` JavaScript
but then execute user's actions asynchronously using the `XMLHttpRequest`
functionality. Which creates a HTTP request and transfers only the part of the
JavaScript functionality. Which creates a HTTP request and transfers only the
website which will be updated.
part of the website which will be updated.
- **client-side approach** - the opposite approach is to transfer the communication
- **client-side approach** - the opposite approach is to transfer the
with the API server and the rendering of the HTML completely from the server directly
communication with the API server and the rendering of the HTML completely
to the client. The client runs the code (usually JavaScript) in his/her web browser
from the server directly to the client. The client runs the code (usually
and the content of the website is generated based on the data received from the API
JavaScript) in his/her web browser and the content of the website is generated
server. The script file is usually quite large but it can be cached and does not
based on the data received from the API server. The script file is usually
have to be downloaded from the server again (until the cached file expires).
quite large but it can be cached and does not have to be downloaded from the
Only the data from the API server needs to be transfered over the Internet and
server again (until the cached file expires). Only the data from the API
thus reduce the volume of payload on each request which leads to a much more
server needs to be transfered over the Internet and thus reduce the volume of
responsive user experience, especially on slower networks. Since the client-side
payload on each request which leads to a much more responsive user experience,
code has full control over the UI and a more sophisticated user interactions
especially on slower networks. Since the client-side code has full control
with the UI can be achieved.
over the UI and a more sophisticated user interactions with the UI can be
achieved.
All of these approaches are used in production by the web developers and all
All of these approaches are used in production by the web developers and all
of them are well documented and there are mature tools for creating websites
of them are well documented and there are mature tools for creating websites
using any of these approaches.
using any of these approaches.
We decided to use the third approach -- to create a fully client-side application
We decided to use the third approach -- to create a fully client-side
which would be familiar and intuitive for a user who is used to modern web
application which would be familiar and intuitive for a user who is used to
applications.
modern web applications.
@todo: please think about more stuff about api and web-app... thanks ;-)
@todo: please think about more stuff about api and web-app... thanks ;-)
@ -1819,18 +1851,16 @@ have to expand the sidebar with a button next to the “*ReCodEx*” title
### Forgotten password
### Forgotten password
If you cannot remember your password and you do not use CASUK
If you cannot remember your password and you do not use CASUK authentication,
authentication, then you can reset your password. You will find a link
then you can reset your password. You will find a link saying “Cannot remember
saying “Cannot remember what your password was? Reset your
what your password was? Reset your password.” under the sign in form. After you
password.” under the sign in form. After you click on this link, you
click on this link, you will be asked to submit your email address. An email
will be asked to submit your email address. An email with a link
with a link containing a special token will be sent to the address you fill in.
containing a special token will be sent to the address you fill in. We
We make sure that the person who requested password resetting is really you.
make sure that the person who requested password resetting is really
When you click on the link (or you copy & paste it into your web browser) you
you. When you click on the link (or you copy & paste it into your web
will be able to select a new password for your account. The token is valid only
browser) you will be able to select a new password for your account. The
for a couple of minutes, so do not forget to reset the password as soon as
token is valid only for a couple of minutes, so do not forget to reset
possible, or you will have to request a new link with a valid token.
the password as soon as possible, or you will have to request a new link
with a valid token.
If you sign in through CASUK, then please follow the instructions
If you sign in through CASUK, then please follow the instructions
provided by the administrators of the service described on their
provided by the administrators of the service described on their