tex: fix typos, reword bits
This commit is contained in:
parent
66e2e901eb
commit
05cbde6ac5
|
@ -93,7 +93,7 @@ file is located using the configuration value
|
|||
\texttt{gpg.format} field needs to be set to \texttt{ssh}. Luckily, because
|
||||
git also allows the configuration values to be local to each repository, both
|
||||
of the mentioned issues can be solved by running the following commands from
|
||||
inside of the cloned repository:
|
||||
inside the cloned repository:
|
||||
|
||||
\vspace{\parskip}
|
||||
\begin{lstlisting}[language=bash, caption={Prepare allowed signers file and signature format for git},
|
||||
|
@ -137,7 +137,7 @@ pipeline step and executes given \emph{commands} inside of it. At the end of
|
|||
each step the container is discarded, while the repository, which is mounted
|
||||
into each container's \texttt{/drone/src} is persisted between steps, allowing
|
||||
it to be cloned only from \emph{origin} only at the start of the pipeline and
|
||||
then shared for all of the following steps, saving bandwidth, time and disk
|
||||
then shared for all the following steps, saving bandwidth, time and disk
|
||||
writes.
|
||||
|
||||
The entire configuration used to run the pipelines can be found in a file named
|
||||
|
@ -189,16 +189,16 @@ The git repository hosting the \texttt{pcmt} configuration schema:\\
|
|||
The repository containing the \LaTeX{} source code of this thesis:\\
|
||||
\url{https://git.dotya.ml/mirre-mt/masters-thesis.git}.
|
||||
|
||||
All of the pertaining source code was published in repositories on a publicly
|
||||
All the pertaining source code was published in repositories on a publicly
|
||||
available git server operated by the author, the reasoning \emph{pro}
|
||||
self-hosting being that it is the preferred way of guaranteed autonomy over
|
||||
one's source code, as opposed to large silos owned by big corporations having a
|
||||
track record of arguably not always deciding with user's best interest in mind
|
||||
(although recourse has been observed~\cite{ytdl}). When these providers act on
|
||||
impulse or under public pressure they can potentially (at least temporarily)
|
||||
disrupt operations of their users. Thus they are not only beholding their users
|
||||
to lengthy \emph{terms of service} that \emph{are subject to change at any
|
||||
given moment}, but also outside factors beyond their control. Granted,
|
||||
disrupt operations of their users. Thus, they are not only beholding their
|
||||
users to lengthy \emph{terms of service} that \emph{are subject to change at
|
||||
any given moment}, but also outside factors beyond their control. Granted,
|
||||
decentralisation can take a toll on discoverability of the project, but that is
|
||||
only a concern if rapid market penetration is a goal, not when aiming for an
|
||||
organically grown community.
|
||||
|
@ -222,7 +222,7 @@ written in Appendix~\ref{appendix:whynix}.
|
|||
ent & ORM using graph-based modelling \\
|
||||
pq & Pure-Go Postgres drivers \\
|
||||
bluemonday & sanitising HTML \\
|
||||
TailwindCSS & utility-first approach to cascading style sheets \\
|
||||
TailwindCSS & utility-first approach to Cascading Style Sheets \\
|
||||
PostgreSQL & persistent data storage \\
|
||||
}
|
||||
|
||||
|
@ -242,8 +242,8 @@ application.
|
|||
}
|
||||
|
||||
Additionally, the dependency-version mapping for the Go program can be inferred
|
||||
from looking at the \texttt{go.mod} file's first \textit{require} block at any
|
||||
point in time. The same can be achieved for \emph{frontend} by glancing at the
|
||||
from looking at the \texttt{go.mod}'s first \textit{require} block at any point
|
||||
in time. The same can be achieved for \emph{frontend} by glancing at the
|
||||
\texttt{package-lock.json} file.
|
||||
|
||||
|
||||
|
@ -324,9 +324,9 @@ runtime, which is a convenient feature in certain situations.
|
|||
|
||||
\n{2}{Authentication}
|
||||
|
||||
The authentication logic is relatively simple and the author attempted to
|
||||
isolate it into a custom \emph{middleware}. User passwords are hashed using a
|
||||
secure KDF before being sent to the database. The KDF of choice is
|
||||
The authentication logic is relatively simple and its core has mostly been
|
||||
isolated into a custom \emph{middleware}. User passwords are hashed using a
|
||||
secure KDF before ever being sent to the database. The KDF of choice is
|
||||
\texttt{bcrypt} (with a sane \emph{Cost} of 10), which automatically includes
|
||||
\emph{salt} for the password and provides ``length-constant'' time hash
|
||||
comparisons. The author plans to add support for the more modern
|
||||
|
@ -362,10 +362,12 @@ the regular build process. \texttt{embed.FS} from the standard library'
|
|||
such as images, logos and stylesheets at the module level. These are then
|
||||
passed around the program as needed, such as to the \texttt{handlers} package.
|
||||
|
||||
There is also a toggle in the application configuration, which can instruct the
|
||||
program at start to either rely entirely on embedded assets or pull live files
|
||||
from the filesystem. The former option makes the application more portable,
|
||||
while the latter allows for flexibility not only during development.
|
||||
There is also a toggle in the application configuration (\texttt{LiveMode}),
|
||||
which can instruct the program at start-up to either rely entirely on embedded
|
||||
assets or pull live template and asset files from the filesystem. The former
|
||||
option makes the application more portable as it is wholly self-contained,
|
||||
while the latter allows for flexibility and customisation not only during
|
||||
development.
|
||||
|
||||
|
||||
\n{2}{Composability}
|
||||
|
@ -396,35 +398,35 @@ executed based on the determined level of access of the user, see
|
|||
Listing~\ref{tmplConditionals} for reference.
|
||||
|
||||
A popular HTML sanitiser \texttt{bluemonday} has been employed to aid with
|
||||
battling XSS. Every template is first run through the sanitiser before being
|
||||
rendered, so that any user-controlled inputs are handled in a safe way.
|
||||
battling XSS. The program first runs every template through the sanitiser
|
||||
before rendering it, so that any user-controlled inputs are handled safely.
|
||||
|
||||
|
||||
\n{2}{Server-side rendering}
|
||||
|
||||
The application constructs the web pages \emph{entirely} on the server side and
|
||||
it runs without a single line of JavaScript, of which the author is especially
|
||||
proud. It improves load times, decreases the attack surface, increases
|
||||
maintainability and reduces cognitive load that is required when dealing with
|
||||
JavaScript. Of course, that requires extensive usage of non-semantic
|
||||
\texttt{POST} requests in web forms even for data updates (where \texttt{PUT}s
|
||||
should be used) and the accompanying frequent full-page refreshes, but that
|
||||
still is not enough to warrant the use of JavaScript.
|
||||
The application constructs the web pages \emph{entirely} on the server side,
|
||||
and it runs without a single line of JavaScript, of which the author is
|
||||
especially proud. It improves load times, decreases the attack surface,
|
||||
increases maintainability and reduces cognitive load that is required when
|
||||
dealing with JavaScript. Of course, that requires extensive usage of
|
||||
non-semantic \texttt{POST} requests in web forms even for data updates (where
|
||||
\texttt{PUT}s should be used) and the accompanying frequent full-page
|
||||
refreshes, but that still is not enough to warrant the use of JavaScript.
|
||||
|
||||
|
||||
\n{2}{Frontend}
|
||||
|
||||
Frontend-side, the application was styled using TailwindCSS, which promotes
|
||||
usage of flexible \emph{utility-first} classes in the markup (HTML) instead of
|
||||
separating out the specific styles out into all-encompasing classes. The author
|
||||
understands this is somewhat of a preference issue and does not hold hard
|
||||
opinions in either direction, however, a note has to be made that this approach
|
||||
empirically allows for a rather quick UI prototyping. Tailwind was chosen
|
||||
partially also because it \emph{looked} nice, had a reasonably detailed
|
||||
separating out the specific styles out into all-encompassing classes. The
|
||||
author understands this is somewhat of a preference issue and does not hold
|
||||
hard opinions in either direction, however, a note has to be made that this
|
||||
approach empirically allows for a rather quick UI prototyping. Tailwind was
|
||||
chosen partially also because it \emph{looked} nice, had a reasonably detailed
|
||||
documentation and offered built-in support for dark/light mode. The templates
|
||||
containing the CSS classes need to be parsed by Tailwind in order to construct
|
||||
the final stylesheet. Upstream provides the original CLI tool called
|
||||
\texttt{tailwindcss},which can be used exactly for that action. Overall, simple
|
||||
\texttt{tailwindcss}, which can be used exactly for that action. Overall, simple
|
||||
and accessible layouts were preferred, a single page was rather split into
|
||||
multiple when becoming convoluted, and data-backed efforts were made to create
|
||||
reasonably contrasting pages.
|
||||
|
@ -443,7 +445,7 @@ WebAssembly was when compared to JavaScript.
|
|||
\n{2}{User isolation}
|
||||
|
||||
Users are allowed into certain parts of the application based on the role they
|
||||
currently posses. For the moment, two basic roles were envisioned, while this
|
||||
currently possess. For the moment, two basic roles were envisioned, while this
|
||||
list might get amended in the future, should the need arise:
|
||||
|
||||
\begin{itemize}
|
||||
|
@ -513,7 +515,7 @@ else should be encrypted.
|
|||
Consequently, both the application operators and the in-application
|
||||
administrators should never be able to learn the details of what the user is
|
||||
tracking, the same being applicable even to potential attackers with direct
|
||||
access to the database. Thus the author maintains that every scenario that
|
||||
access to the database. Thus, the author maintains that every scenario that
|
||||
could potentially lead to a data breach (apart from a compromised user machine
|
||||
and the like) would have to entail some form of operating memory acquisition,
|
||||
for instance using \texttt{LiME}~\cite{lime}, or perhaps directly the
|
||||
|
@ -600,7 +602,7 @@ The main configuration comprises both raw attributes and child records, which
|
|||
allow for grouping of related functionality. For instance, configuration
|
||||
settings pertaining mailserver setup are grouped in a record named
|
||||
\textbf{Mailer}. Its attribute \textbf{Enabled} is annotated as \textbf{Bool},
|
||||
which was deemed appropriate for a on-off switch-like functionality, with the
|
||||
which was deemed appropriate for an on-off switch-like functionality, with the
|
||||
only permissible values being either \emph{True} or \emph{False}.
|
||||
|
||||
Do note that in Dhall $true\ != True$, since internally \textbf{True} is a
|
||||
|
@ -699,7 +701,7 @@ and is required to authenticate for all sensitive operations. To not only know
|
|||
\emph{who} the user is but also make sure they are \emph{permitted} to perform
|
||||
the action they are attempting, the program employs an \emph{authorisation}
|
||||
mechanism in the form of sessions. These are on the client side represented by
|
||||
cryptographically signed and encrypted (using 256 bit AES) HTTP cookies. That
|
||||
cryptographically signed and encrypted (using 256-bit AES) HTTP cookies. That
|
||||
lays foundations for a few things: the data saved into the cookies can be
|
||||
regarded as private because short of future \emph{quantum computers} only the
|
||||
program itself can decrypt and access the data, and the data can be trusted
|
||||
|
@ -707,7 +709,7 @@ since it is both signed using the key that only the program controls and
|
|||
\emph{encrypted} with \emph{another} key that equally only the program holds.
|
||||
|
||||
The cookie data is only ever written \emph{or} read at the server side,
|
||||
solidifying the authors decision to let it be encrypted, as there is not point
|
||||
solidifying the authors decision to let it be encrypted, as there is no point
|
||||
in not encrypting it for some perceived client-side simplification. Users
|
||||
navigating the website send their session cookie (if it exists) with
|
||||
\textbf{every request} to the server, which subsequently verifies the integrity
|
||||
|
@ -741,7 +743,7 @@ The database schema is not being created by manually typing out SQL statements.
|
|||
Instead, an Object-relational Mapping (ORM) tool named \texttt{ent} is used,
|
||||
which allows defining the table schema and relations entirely in Go. The upside
|
||||
of this approach is that the \emph{entity} types are natively understood by
|
||||
code editors and they also get type-checked by the compiler for correctness,
|
||||
code editors, and they also get type-checked by the compiler for correctness,
|
||||
preventing all sorts of headaches and potential bugs.
|
||||
|
||||
Since \texttt{ent} encourages the usage of \emph{declarative migrations} at
|
||||
|
@ -776,7 +778,7 @@ following:
|
|||
These methods can further be imported into other packages and this makes
|
||||
working with the database a morning breeze.
|
||||
|
||||
All of the database \empg{entity} IDs were declared as type \texttt{UUID}
|
||||
All the database \empg{entity} IDs were declared as type \texttt{UUID}
|
||||
(\emph{universally unique ID, theoretically across space and time}), contrary
|
||||
to the more traditional \emph{integer} IDs.
|
||||
|
||||
|
@ -784,7 +786,7 @@ Support for \texttt{UUID}s was provided natively by the supported databases and
|
|||
in Go via a popular and vetted open-source library
|
||||
(\url{github.com/google/uuid}). Among the upsides of using \texttt{UUID}s over
|
||||
integer IDs is that there is no need to manually increment the ID. But more
|
||||
importantly, there is also the fact that compared to 32 bit\footnotemark{}
|
||||
importantly, there is also the fact that compared to 32-bit\footnotemark{}
|
||||
signed integers the \texttt{UUID} is a somewhat randomly generated 16 byte (128
|
||||
bit) array, reducing chances of collision.
|
||||
|
||||
|
@ -792,7 +794,7 @@ Barring higher chances of preventing conflicts during imports of foreign
|
|||
databases, this design decision might not provide any advantage for the current
|
||||
system \emph{at the moment}. It could, however, hold importance in the future,
|
||||
should the database ever be deployed in a replicated, high-availability (HA)
|
||||
manner with more that one concurrent \emph{writer} (replicated application
|
||||
manner with more than one concurrent \emph{writer} (replicated application
|
||||
instances).
|
||||
|
||||
\footnotetext{In Go, integer size is architecture dependent, see
|
||||
|
@ -827,8 +829,8 @@ Since the program also needs a database for proper functioning, an example
|
|||
scenario includes the application container being run in a Podman \textbf{pod}
|
||||
(as in a pea pod or pod of whales) together with the database. That results in
|
||||
not having to expose the database to the entire host or out of the pod at all,
|
||||
it is only be available over pod's \texttt{localhost}. Hopefully it goes
|
||||
without saying that the default values of any configuration secrets should be
|
||||
it is only available over pod's \texttt{localhost}. Hopefully it goes without
|
||||
saying that the default values of any configuration secrets should be
|
||||
substituted by the application operator with new, securely generated ones.
|
||||
|
||||
|
||||
|
@ -984,7 +986,7 @@ Host network: false
|
|||
|
||||
To be absolutely sure that the database is available only internally in the pod
|
||||
(unless, of course, there is another process listening on the subject port),
|
||||
and that connecting to the database from outside of the pod (i.e. from the
|
||||
and that connecting to the database from outside the pod (i.e. from the
|
||||
container host) really \emph{does} fail, the following commands can be issued:
|
||||
|
||||
\begin{lstlisting}[language=bash, caption={In-pod database is unreachable from
|
||||
|
@ -1076,8 +1078,8 @@ server {
|
|||
\end{lstlisting}
|
||||
\vspace*{-\baselineskip}
|
||||
|
||||
The configuration describes how traffic arriving at port \texttt{80/tcp} (IPv4
|
||||
or IPv6) that matches the domain name(s) \texttt{\{www.,\}<pcmt domain>}
|
||||
The snippet describes how traffic arriving at port \texttt{80/tcp} (IPv4 or
|
||||
IPv6) that matches the domain name(s) \texttt{\{www.,\}<pcmt domain>}
|
||||
(\texttt{<pcmt domain>} being the domain name that the program was configured
|
||||
with, including appropriate DNS records) gets 301-redirected to the same
|
||||
location (\texttt{\$request\_uri}), only over \texttt{HTTPS}. If the server
|
||||
|
@ -1106,7 +1108,7 @@ testing everything or writing tests prior to business logic code. Arguably,
|
|||
following the practice of TDD should result in writing a \emph{better designed}
|
||||
code, particularly because there needs to be a prior thought about the shape
|
||||
and function of the code, as it is tested for before it is even written, but it
|
||||
adds an slight inconvenience to what is otherwise a straightforward process.
|
||||
adds a slight inconvenience to what is otherwise a straightforward process.
|
||||
|
||||
Thanks to Go's built in support for testing via its \texttt{testing} package
|
||||
and the tooling in the \texttt{go} tool, writing tests is relatively simple. Go
|
||||
|
@ -1117,12 +1119,12 @@ found on any path using the ellipsis, like so: \texttt{go test
|
|||
reports some statistics, such as the time it took to run the test or whether it
|
||||
succeeded or failed. To be precise, the test files also need to contain test
|
||||
functions, which are functions with the signature \texttt{func TestWhatever(t
|
||||
*testing.T)\{\}} and where the function prefix ``Test'' is equally as important
|
||||
as the signature. Without it, the function is not considered to be a testing
|
||||
*testing.T)\{\}} and where the function prefix ``Test'' is just as important as
|
||||
the signature. Without it, the function is not considered to be a testing
|
||||
function despite having the required signature and is therefore \emph{not}
|
||||
executed during testing.
|
||||
|
||||
This test lookup behaviour; however, also has a neat side-effect: all the test
|
||||
This test lookup behaviour; however, also has a neat side effect: all the test
|
||||
files can be kept side-by-side their regular source counterparts, there is no
|
||||
need to segregate them into a specially blessed \texttt{tests} folder or
|
||||
similar, which in author's opinion improves readability. As a failsafe, in case
|
||||
|
@ -1151,20 +1153,20 @@ then after pushing to remote in the CI.
|
|||
|
||||
\n{3}{func TestUserExists(t *testing.T)}
|
||||
|
||||
An example integration test shown in Listing~\ref{integrationtest} can be seen
|
||||
at line 10 to declare a helper function \texttt{getCtx() context.Context},
|
||||
In the integration test shown in Listing~\ref{integrationtest}, it is prefaced
|
||||
at line 10 by declaring a helper function \texttt{getCtx() context.Context},
|
||||
which takes no arguments and returns a new\\ \texttt{context.Context}
|
||||
initialised with the value of the global logger, which is how the logger gets
|
||||
injected into the user module functions. The actual test function with the
|
||||
signature \texttt{TestUserExists(t *testing.T)} defines a database connection
|
||||
string at line 21 and attempts to open a connection to the database. The
|
||||
database in use here is SQLite3 running in memory mode, meaning no file is
|
||||
actually written to disk during this process. Since the testing data is not
|
||||
needed after the test, this is desirable. Next, a defer statement calls the
|
||||
\texttt{Close()} method on the database object , which is the Go idiomatic way
|
||||
of closing files and network connections (which are also an abstraction over
|
||||
files on UNIX-like operating systems such as GNU/Linux). Contrary to where it
|
||||
is declared, the \emph{defer} statement is onlycalled after all of the
|
||||
initialised with the value of the global logger. As previously mentioned, that
|
||||
is how the logger gets injected into the user module functions. The actual test
|
||||
function with the signature \texttt{TestUserExists(t *testing.T)} defines a
|
||||
database connection string at line 21 and attempts to open a connection to the
|
||||
database. The database in use here is SQLite3 running in memory mode, meaning
|
||||
no file is actually written to disk during this process. Since the testing data
|
||||
is not needed after the test, this is desirable. Next, a defer statement calls
|
||||
the \texttt{Close()} method on the database object, which is the Go idiomatic
|
||||
way of closing files and network connections (which are also an abstraction
|
||||
over files on UNIX-like operating systems such as GNU/Linux). Contrary to where
|
||||
it is declared, the \emph{defer} statement is only called after all the
|
||||
statements in the surrounding function, which makes sure no file descriptors
|
||||
(FDs) are leaked and the file is properly closed when the function returns.
|
||||
|
||||
|
@ -1194,7 +1196,7 @@ function is again checked (line 33) and if everything goes well, the
|
|||
|
||||
\smallskip
|
||||
\smallskip
|
||||
\begin{lstlisting}[language=Go, caption={Example integration test.},
|
||||
\begin{lstlisting}[language=Go, caption={User existence integration test},
|
||||
label=integrationtest,basicstyle=\linespread{0.9}\scriptsize\ttfamily,
|
||||
backgroundcolor=\color{lstbg},
|
||||
numbers=left,
|
||||
|
@ -1274,7 +1276,7 @@ fail.
|
|||
|
||||
The final statements of the described test attempts to create a user by calling
|
||||
the function \texttt{CreateUser(...)} at line 46, whose return values are again
|
||||
checked for both error and \emph{nilability}, respectively. The test continues
|
||||
checked for both error and \emph{nillability}, respectively. The test continues
|
||||
with more of the checks similar to what has been described so far, but the rest
|
||||
was omitted for brevity.
|
||||
|
||||
|
@ -1380,7 +1382,7 @@ domain, with the overall grade being A+.
|
|||
|
||||
\n{1}{Application screenshots}
|
||||
|
||||
Figure~\ref{fig:homepage} depicts the initial page that a logged out user is
|
||||
Figure~\ref{fig:homepage} depicts the initial page that a logged-out user is
|
||||
greeted with when they load the application.
|
||||
|
||||
\obr{Homepage}{fig:homepage}{.84}{graphics/screen-homepage}
|
||||
|
@ -1502,8 +1504,8 @@ top of the page, as shown in Figure~\ref{fig:adminUserDeletePostHoc}.
|
|||
Figure~\ref{fig:manageAPIKeys} shows a page that allows administrators to
|
||||
manage instance-wide API keys for external services, such as \emph{Have I Been
|
||||
Pwned?} or \emph{DeHashed.com}. Do note that these keys are never distributed
|
||||
to clients in any way and are always only used by the application itself to
|
||||
make the requests on behalf of its users.
|
||||
to clients in any way and are only ever used by the application itself to make
|
||||
the requests on \emph{behalf} of the users.
|
||||
|
||||
\obr{Log-out message}
|
||||
{fig:logout}{.30}
|
||||
|
|
Reference in New Issue