This guide corresponds to the source code located (relative to the project root)
at server/eclipse-project/src/main/java/us/freeandfair/corla/
.
Each of the top-level directories is a Java package. An overview of each is included along with links to interesting code snippets.
This is where code related to the abstract state machine lives. Please read the linked guide on what an abstract state machine is and why it was included in the codebase.
The auth
package primarily contains the interface to authentication backends.
The backend used by the Colorado Department of State is EntrustAuthentication
,
which implements the AuthenticationInterface
from this package. That Entrust
authentication backend is plugged in by naming the class in the Java system
properties for the application.
In addition to the interesting files below, there are a number of supporting classes. However, these are key to understanding the system:
AbstractAuthentication.java
: This contains authentication code common to all authentication methods. If you only need to make a change to the way authentication occurs with Entrust, you should modify that proprietary Java class. Otherwise, if it is common to all authentication methods, it should probably be added here.AuthenticationInterface.java
: The interface that must be satisfied for all authentication methods.
Coordination and orchestration of the application. endpoint
s will often invoke
a method in here, which may in turn make requests to the data model. Many times,
execution paths through the code will take a route like this, where each of the
names below corresponds to a package described in this document:
endpoint ->(calls) controller ->(calls) model/query
endpoint <-(returns) controller <-(returns) model/query
so if you are looking to get started with a given action, it is recommended that
you take a look at classes in controller
or endpoint
.
Nearly all of the classes in this package are crucial to the operation of the application.
AuditReport.java
: See Javadoc.BallotSelection.java
: Coordination for ballot selection queriesComparisonAuditController.java
: This is one of the most important classes in the system. This orchestrates nearly all of the important behavior of the application.ContestCounter.java
: Orchestrates calculations for vote tallies across contests (contrasted with the original code which only calculated votes within counties).DeleteFileController.java
: Orchestrator for requests which delete files. "Files" is a generic term including, and currently limited to, ballot manifests and CVR exports.ImportFileController.java
: Orchestrator for requests which read and import files that have previously been uploaded. So, this controller is not responsible for the uploading of the file into the system, but is responsible for the process of extracting useful information out of that file and into the database.
Core cryptographic functionality for the application is located here. There is not a lot of code, but it deals with the SHA-256 hash implementation for checking uploaded files as well as the pseudorandom number generator which drives ballot selection.
For more about the method of pseudorandom number generation, consult Ron Rivest's reference implementation. The two implementations should generate the same numbers (outputs) given the same inputs.
This package is responsible for the actual parsing of the ballot manifest and CVR export files, both in CSV format. The package name may be a bit misleading and overly specific, as uploaded files could, in the future, be in one of several formats, but currently only CSV is handled.
The parsers currently implement interfaces for future extensibility which are located in this package, but there is only one real implementation for each of the ballot manifest and CVR export parser interfaces.
ColoradoBallotManifestParser.java
: The ballot manifest parser implementation.DominionCVRExportParser.java
: The CVR export parser implementation.
All of the HTTP endpoints are handled by classes in this package. Typically, code in this package will invoke a controller to orchestrate a particular set of actions.
The reason Spark was chosen by Free and Fair over something more traditional such as Spring is unknown, but the author's assumption is that Spark provided a minimal framework from which to start the project, without constraining the architecture. At this point in time, it would be worth evaluating whether that tradeoff still holds.
Endpoint.java
: The Java interface that all of the endpoints must implement.AbstractEndpoint.java
: Code common to all endpoint classes. It is recommended that you read this first, because subclassing code will often refer to methods in this class.AbstractAuditBoardDashboardEndpoint.java
: Imposes some authorization restrictions so that audit boards are allowed to access endpoints subclassing this class.AbstractCountyDashboardEndpoint.java
: Imposes some authorization restrictions so that county-level users are allowed to access endpoints subclassing this class.AbstractDoSDashboardEndpoint.java
: Imposes some authorization restrictions so that state-level users are allowed to access endpoints subclassing this class.
These classes are used with Google's GSON library. Their main purpose is to describe common structures so that you can easily transform data between JSON and Java classes.
Commonly, the classes will be used in the following way:
MyStructure structure = Main.GSON.fromJson(someJsonString, MyStructure.class);
If you commonly parse JSON into a Java data structure or marshal the same Java data structure into JSON, consider putting that code into a class in this package.
FreeAndFairNamingStrategy.java
: Free and Fair uses a specific naming convention in their Java classes. Class members are prefixed withmy_
in the Free and Fair naming strategy. GSON supports automatic translation of Java class members into JSON field names, and this class implements this strategy by stripping out themy_
prefix, since it does not have meaning outside of the Java class names.
Implements the core risk-limiting audit calculations used by the system. The
class Audit.java
contains detailed comments describing where the
calculations come from, since they are mostly derived directly from the
literature.
The model
classes mostly implement Hibernate ORM persistent
entities, and so directly correspond to the PostgreSQL database tables and
columns. Placing business logic in these classes is discouraged, and if you find
it, should be factored out into a controller
or elsewhere.
It is important to understand how the Hibernate ORM works before adding new classes to the system, so if you are not familiar with Hibernate, check out a guide on the Hibernate site.
Much like the json
package, persistence
is all about common transformations
to and from Java code, but instead of strictly dealing with JSON (frequently
used to communicate with the outside world), these classes are more about
transforming data so that it can be persisted to the PostgreSQL database. In
some cases, complex structures are serialized as JSON and stored as strings in
database tables. When these columns are read back, they are deserialized and
stored as Map
s or custom objects.
Persistence.java
: This is another very important class in the system, and you will see references to it throughout the software. This class wraps the Hibernate API with useful methods specific to the Colorado RLA application and the methods of database access that Free and Fair preferred. You will want to read through it to understand how method calls in the software translate to the Hibernate API.
Classes wrapping complex database queries. While quite a bit of database work
can be done through the simple CRUD functionality provided by Hibernate,
reporting (for example) requires more complex queries, and those live in the
query
package.
Classes generating common reports in the system, and supporting functionality. If you are looking to modify any aspect of a report generated by the system, start looking in here.
No project would be complete without some kind of util
package, now would it?
The classes in util
do not easily fit into any of the other packages, and may
represent very common functionality used across the system, such as custom
comparators for sorting strings with numbers in them.
Some of the naming conventions used in the code and established by Free and Fair may be unfamiliar to Java developers. Namely:
- the
my_
prefix, which is a convention used to denote object members, and - the
the_
prefix, which is a convention used to denote method arguments.
One reason these conventions were established was to avoid bugs that could arise out of ambiguity allowed by Java. For instance, Java allows something like the following class:
class Foo {
private String name;
public Foo(String name) {
name = name;
}
}
The ambiguity of the identifier name
could be a potential source of bugs: in a
longer method, name
could refer to a local variable and get overwritten when
you may have intended to set the object member identified by name
, as an
example. By using the_name
and my_name
to refer to the method argument and
object member, respectively, the ambiguity disappears, and the use of those
prefixes can be enforced by a style checker.
The constraints on naming has since been relaxed to be more comfortable to more
traditional Java developers, and there are other methods, enforceable by
tooling, of automatically detecting and preventing the sorts of bugs described
above that do not add my_
and the_
prefixes to identifiers in the code.
Which one you choose is a matter of taste, and you should pick the style that makes sense for your team.