Skip to content

Commit b8a125f

Browse files
Merge branch 'master' of https://github.com/paragonie/chronicle
# Conflicts: # sql/sqlite/00-local.sql # sql/sqlite/01-remote.sql
2 parents 27bb22d + 0836574 commit b8a125f

File tree

12 files changed

+287
-105
lines changed

12 files changed

+287
-105
lines changed

.travis.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,31 @@ matrix:
1212
allow_failures:
1313
- php: "nightly"
1414

15+
services:
16+
- mysql
17+
- postgresql
18+
19+
before_install:
20+
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
21+
- psql -c 'create database travis_ci_test;' -U postgres
22+
1523
install:
1624
- composer self-update
1725
- composer update
18-
- php bin/install.php
19-
- php bin/make-tables.php
2026

2127
script:
28+
# Test SQLite
29+
- php bin/install.php
30+
- php bin/make-tables.php
31+
- composer test
32+
- composer static-analysis
33+
# Test MySQL
34+
- php bin/install.php --mysql --host 127.0.0.1 -u root --database test
35+
- php bin/make-tables.php
36+
- composer test
37+
- composer static-analysis
38+
# Test PostgreSQL
39+
- php bin/install.php --pgsql -u postgres --database travis_ci_test
40+
- php bin/make-tables.php
2241
- composer test
2342
- composer static-analysis

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ as part of our continued efforts to make the Internet more secure.
3030
* [How to write (publish) to your Chronicle](docs/02-publish.md)
3131
* [How to setup cross-signing to other Chronicles](docs/03-cross-signing.md)
3232
* [How to replicate other Chronicles](docs/04-replication.md)
33+
* [Concurrent Instances](docs/05-instances.md)
34+
* [Internal Developer Documentation](docs/internals)
35+
* [Design Philosophy](docs/internals/01-design-philosophy.md)
36+
* [SQL Tables](docs/internals/02-sql-tables.md)
3337

3438
### Client-Side Software that Interacts with Chronicle
3539

bin/create-client.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
$settings['database']['options'] ?? []
3737
);
3838

39+
// Pass database instance to Chronicle
40+
Chronicle::setDatabase($db);
41+
3942
/**
4043
* @var Getopt $getopt
4144
*
@@ -110,9 +113,13 @@
110113
/** @var string $newPublicId */
111114
$newPublicId = Base64UrlSafe::encode(\random_bytes(24));
112115

116+
// Disable escaping for SQLite
117+
/** @var boolean $isSQLite */
118+
$isSQLite = strpos($settings['database']['dsn'] ?? '', 'sqlite:') !== false;
119+
113120
$db->beginTransaction();
114121
$db->insert(
115-
Chronicle::getTableName('clients'),
122+
Chronicle::getTableName('clients', $isSQLite),
116123
[
117124
'isAdmin' => !empty($admin),
118125
'publicid' => $newPublicId,

bin/install.php

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<?php
22
declare(strict_types=1);
33

4+
use GetOpt\{
5+
GetOpt,
6+
Option
7+
};
48
use ParagonIE\Sapient\CryptographyKeys\SigningSecretKey;
59

610
/** @var string $root */
@@ -18,11 +22,74 @@
1822
$signingKey->getString()
1923
);
2024

25+
/**
26+
* @var Getopt $getopt
27+
*
28+
* This defines the Command Line options.
29+
*
30+
* These are many examples:
31+
* php install.php
32+
* php install.php --mysql
33+
* php install.php --pgsql
34+
* php install.php --sqlite
35+
* php install.php --mysql --host localhost --port 3306 --username mysql_user --password mysql_password
36+
* php install.php --pgsql --host=localhost --port=5432 --username=pgsql_user --password=pgsql_password
37+
* php install.php --mysql --h localhost --port 3306 --u mysql_user --p mysql_password
38+
* php install.php --pgsql --h=localhost --port=5432 --u=pgsql_user --p=pgsql_password
39+
* php install.php --sqlite --database chronicle
40+
* php install.php --sqlite --database=chronicle --extension db
41+
*/
42+
$getopt = new Getopt([
43+
new Option(null, 'mysql', Getopt::OPTIONAL_ARGUMENT),
44+
new Option(null, 'pgsql', Getopt::OPTIONAL_ARGUMENT),
45+
new Option(null, 'sqlite', Getopt::OPTIONAL_ARGUMENT),
46+
new Option('h', 'host', Getopt::OPTIONAL_ARGUMENT),
47+
new Option(null, 'port', Getopt::OPTIONAL_ARGUMENT),
48+
new Option('d', 'database', Getopt::OPTIONAL_ARGUMENT),
49+
new Option('e', 'extension', Getopt::OPTIONAL_ARGUMENT),
50+
new Option('u', 'username', Getopt::OPTIONAL_ARGUMENT),
51+
new Option('p', 'password', Getopt::OPTIONAL_ARGUMENT),
52+
]);
53+
$getopt->process();
54+
55+
/** @var string $mysql */
56+
$mysql = $getopt->getOption('mysql') ?? false;
57+
/** @var string $pgsql */
58+
$pgsql = $getopt->getOption('pgsql') ?? false;
59+
/** @var string $sqlite */
60+
$sqlite = $getopt->getOption('sqlite') ?? (!$mysql && !$pgsql);
61+
/** @var string $host */
62+
$host = $getopt->getOption('host') ?? 'localhost';
63+
/** @var string $port */
64+
$port = $getopt->getOption('port') ?? ($mysql ? '3306' : ($pgsql ? '5432' : ''));
65+
/** @var string $database */
66+
$database = $getopt->getOption('database') ?? 'chronicle';
67+
/** @var string $extension */
68+
$extension = $getopt->getOption('extension') ?? 'db';
69+
/** @var string $username */
70+
$username = $getopt->getOption('username') ?? ($mysql ? 'mysqluser' : ($pgsql ? 'pgsqluser' : ''));
71+
/** @var string $password */
72+
$password = $getopt->getOption('password') ?? '';
73+
74+
// default SQLite
75+
$databaseConfig = [
76+
'dsn' => 'sqlite:' . $root . '/local/' . $database . '.' . $extension,
77+
];
78+
79+
if(!$sqlite){
80+
81+
$dbType = $mysql ? 'mysql' : 'pgsql';
82+
83+
$databaseConfig = [
84+
'dsn' => $dbType . ':host=' . $host . ';port=' . $port . ';dbname=' . $database,
85+
'username' => $username,
86+
'password' => $password,
87+
];
88+
}
89+
2190
// Write the default settings to the local settings file.
2291
$localSettings = [
23-
'database' => [
24-
'dsn' => 'sqlite:' . $root . '/local/chronicle.sql'
25-
],
92+
'database' => $databaseConfig,
2693
// Map 'channel-name' => 'table_prefix'
2794
'instances' => [
2895
'' => ''

docs/01-setup.md

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ General process:
99
1. Clone this repository: `git clone https://github.com/paragonie/chronicle.git`
1010
2. Run `composer install`
1111
* If you don't have Composer, [go here for **Composer installation** instructions](https://getcomposer.org/download/).
12-
3. Run `bin/install.php` to generate a keypair and basic configuration file.
12+
3. Run `php bin/install.php` to generate a keypair and basic configuration file.
1313
4. Edit `local/settings.json` to configure your Chronicle. For example, you
1414
can choose a MySQL, PostgreSQL, or SQLite backend. [See below](#configuring-localsettingsjson).
15-
5. Run `bin/make-tables.php` to setup the database tables
15+
5. Run `php bin/make-tables.php` to setup the database tables
1616
6. Configure a new virtual host for Apache/nginx/etc. to point to the `public`
1717
directory, **OR** run `composer start` to launch the built-in web server.
1818

@@ -28,6 +28,14 @@ except with information pertinent to your instance and your public key:
2828

2929
### MySQL
3030

31+
To generate MySQL config simply do the following:
32+
33+
```shell
34+
php bin/install.php --mysql
35+
```
36+
37+
The output will be like this:
38+
3139
```json
3240
{
3341
"database": {
@@ -38,8 +46,35 @@ except with information pertinent to your instance and your public key:
3846
"signing-public-key": "gIQOvAxVbF2zLeanIZDQe7S2gBsabfxM3vP8sjBI_08="
3947
}
4048
```
49+
50+
There are many available options:
51+
52+
```shell
53+
php bin/install.php --mysql \
54+
--host localhost \
55+
--port 3306 \
56+
--database chronicle \
57+
--username mysql_user \
58+
--password mysql_password
59+
```
60+
61+
Short format options:
62+
63+
```shell
64+
php bin/install.php --mysql -h localhost --port 3306 \
65+
-d chronicle -u mysql_user -p mysql_password
66+
```
67+
4168
### PostgreSQL
4269

70+
To generate PostgreSQL config simply do the following:
71+
72+
```shell
73+
php bin/install.php --pgsql
74+
```
75+
76+
The output will be like this:
77+
4378
```json
4479
{
4580
"database": {
@@ -51,8 +86,34 @@ except with information pertinent to your instance and your public key:
5186
}
5287
```
5388

89+
There are many available options:
90+
91+
```shell
92+
php bin/install.php --pgsql \
93+
--host localhost \
94+
--port 5432 \
95+
--database chronicle \
96+
--username pgsql_user \
97+
--password pgsql_password
98+
```
99+
100+
Short format options:
101+
102+
```shell
103+
php bin/install.php --pgsql -h localhost --port 5432 \
104+
-d chronicle -u pgsql_user -p mysql_password
105+
```
106+
54107
### SQLite
55108

109+
To generate SQLite config simply do the following:
110+
111+
```shell
112+
php bin/install.php
113+
```
114+
115+
The output will be like this:
116+
56117
```json
57118
{
58119
"database": {
@@ -61,6 +122,17 @@ except with information pertinent to your instance and your public key:
61122
"signing-public-key": "gIQOvAxVbF2zLeanIZDQe7S2gBsabfxM3vP8sjBI_08="
62123
}
63124
```
125+
There are many available options:
126+
127+
```shell
128+
php bin/install.php --sqlite --database live --extension db
129+
```
130+
131+
Short format options:
132+
133+
```shell
134+
php bin/install.php --sqlite -d live -e db
135+
```
64136

65137

66138
## How to add clients to your Chronicle

sql/mysql/00-local.sql

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CREATE TABLE chronicle_clients (
22
`id` BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
3-
`publicid` VARCHAR(128),
4-
`publickey` TEXT,
3+
`publicid` VARCHAR(128) NOT NULL,
4+
`publickey` TEXT NOT NULL,
55
`isAdmin` BOOLEAN NOT NULL DEFAULT FALSE,
66
`comment` TEXT,
77
`created` DATETIME DEFAULT CURRENT_TIMESTAMP,
@@ -24,5 +24,6 @@ CREATE TABLE chronicle_chain (
2424
INDEX(`currhash`),
2525
INDEX(`summaryhash`),
2626
FOREIGN KEY (`prevhash`) REFERENCES chronicle_chain(`currhash`) ON DELETE RESTRICT ON UPDATE RESTRICT,
27-
UNIQUE(`prevhash`)
28-
);
27+
UNIQUE(`prevhash`),
28+
UNIQUE(`currhash`)
29+
);

sql/mysql/01-remote.sql

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
CREATE TABLE chronicle_xsign_targets (
22
`id` BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
3-
`name` TEXT,
4-
`url` TEXT,
5-
`clientid` TEXT,
6-
`publickey` TEXT,
7-
`policy` TEXT,
3+
`name` TEXT NOT NULL,
4+
`url` TEXT NOT NULL,
5+
`clientid` TEXT NOT NULL,
6+
`publickey` TEXT NOT NULL,
7+
`policy` TEXT NOT NULL,
88
`lastrun` TEXT
99
);
1010

1111
CREATE TABLE chronicle_replication_sources (
1212
`id` BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
13-
`uniqueid` TEXT,
14-
`name` TEXT,
15-
`url` TEXT,
16-
`publickey` TEXT
13+
`uniqueid` TEXT NOT NULL,
14+
`name` TEXT NOT NULL,
15+
`url` TEXT NOT NULL,
16+
`publickey` TEXT NOT NULL
1717
);
1818

1919
CREATE TABLE chronicle_replication_chain (
2020
`id` BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
21-
`source` BIGINT UNSIGNED REFERENCES chronicle_replication_sources(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
22-
`data` TEXT,
21+
`source` BIGINT UNSIGNED NOT NULL REFERENCES chronicle_replication_sources(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
22+
`data` TEXT NOT NULL,
2323
`prevhash` VARCHAR(128) NULL,
2424
`currhash` VARCHAR(128) NOT NULL,
25-
`hashstate` TEXT,
25+
`hashstate` TEXT NOT NULL,
2626
`summaryhash` VARCHAR(128),
27-
`publickey` TEXT,
28-
`signature` TEXT,
27+
`publickey` TEXT NOT NULL,
28+
`signature` TEXT NOT NULL,
2929
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
3030
`replicated` TIMESTAMP NULL,
3131
INDEX(`prevhash`),

sql/pgsql/00-local.sql

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CREATE TABLE chronicle_clients (
22
id BIGSERIAL PRIMARY KEY,
3-
publicid TEXT,
4-
publickey TEXT,
3+
publicid TEXT NOT NULL,
4+
publickey TEXT NOT NULL,
55
"isAdmin" BOOLEAN NOT NULL DEFAULT FALSE,
66
comment TEXT,
77
created TIMESTAMP,
@@ -12,16 +12,17 @@ CREATE INDEX chronicle_clients_clientid_idx ON chronicle_clients(publicid);
1212

1313
CREATE TABLE chronicle_chain (
1414
id BIGSERIAL PRIMARY KEY,
15-
data TEXT,
15+
data TEXT NOT NULL,
1616
prevhash TEXT NULL,
17-
currhash TEXT,
18-
hashstate TEXT,
19-
summaryhash TEXT,
20-
publickey TEXT,
21-
signature TEXT,
17+
currhash TEXT NOT NULL,
18+
hashstate TEXT NOT NULL,
19+
summaryhash TEXT NOT NULL,
20+
publickey TEXT NOT NULL,
21+
signature TEXT NOT NULL,
2222
created TIMESTAMP,
23-
FOREIGN KEY (currhash) REFERENCES chronicle_chain(prevhash),
24-
UNIQUE(prevhash)
23+
UNIQUE(currhash),
24+
UNIQUE(prevhash),
25+
FOREIGN KEY (prevhash) REFERENCES chronicle_chain(currhash)
2526
);
2627

2728
CREATE INDEX chronicle_chain_prevhash_idx ON chronicle_chain(prevhash);

0 commit comments

Comments
 (0)