Giter Club home page Giter Club logo

chronicle's People

Contributors

aidantwoods avatar berteltorp avatar lookyman avatar paragonie-scott avatar paragonie-security avatar pplnevstokes avatar soatok avatar vzool avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chronicle's Issues

Basic REST API

We need to support the following basic operations:

  • Publish a message to the hash chain, get its hash and summary hash
  • Get the latest hash
  • Lookup a data entry by its hash
  • List all of the hashes since a given hash
  • Export the entire hash chain

Additionally, we may want to add two additional capabilities for privileged users:

  • Register a new public key for a new client
    • (Optional): Add the new public key to the hash chain
  • Revoke a public key for a client
    • (Optional): Add the revocation to the hash chain

Invalid identifier: Invalid characters supplied.

When running:

php bin/scheduled-tasks.php

Sometimes this is generated:

PHP Fatal error:  Uncaught ParagonIE\EasyDB\Exception\InvalidIdentifier: Invalid identifier: Invalid characters supplied. in /var/www/vhosts/domain.com/vendor/paragonie/easydb/src/EasyDB.php:295
Stack trace:
#0 /var/www/vhosts/domain.com/vendor/paragonie/easydb/src/EasyDB.php(745): ParagonIE\EasyDB\EasyDB->escapeIdentifier('"chronicle_chai...')
#1 /var/www/vhosts/domain.com/vendor/paragonie/easydb/src/EasyDB.php(512): ParagonIE\EasyDB\EasyDB->buildInsertQueryBoolSafe('"chronicle_chai...', Array)
#2 /var/www/vhosts/domain.com/src/Chronicle/Chronicle.php(153): ParagonIE\EasyDB\EasyDB->insert('"chronicle_chai...', Array)
#3 /var/www/vhosts/domain.com/src/Chronicle/Process/Attest.php(153): ParagonIE\Chronicle\Chronicle::extendBlakechain('{\n    "version"...', 'IryGC1_n2byTv9W...', Object(ParagonIE\Sapient\CryptographyKeys\SigningPublicKey))
#4 /var/www/vhosts/domain.com/src/Chronicle in /var/www/vhosts/domain.com/vendor/paragonie/easydb/src/EasyDB.php on line 295

I have no clue why... I'm running an empty Chronicle with the default sqlite db and a single replica (https://php-chronicle.pie-hosted.com/chronicle).

The replica seems to be running fine but this error puzzles me and makes me think something is not going ok... any clue?

Cross-Signing

It should be possible to automatically cross-sign new hashes and summary hashes to other Chronicle instances. This will require the following information:

  1. The SigningPublicKey of each peer.
  2. The URL of each peer.
  3. The policy.
    • Once per day? Once per hour?
    • Once per 10 updates?
    • Triggered by every update?

This implies that, server-side, we have a way to rate-limit the number of hashes per client.

Unable to retrieve entry containing binary data

Hi,

I added a new encrypted entry to the chain (data encrypted with Sapient\SealingPublicKey). When I try to retrieve the entry for that hash using the lookup api route or export the whole chain, I receive the following error response:

{ "version": "1.0.x", "datetime": "2018-10-19T15:36:07+02:00", "status": "ERROR", "message": "Cannot JSON-encode this message." }

I checked the data stored in the chronicle_chain table for that hash and I found out that it is stored in binary form:

grafik

I think the data should either be stored in an encoded form or appropriate encoding should applied to ensure retrieval via REST API is possible.

Best regards,
Ben

PostgreSQL Invalid foreign key: there is no unique constraint matching given keys for referenced table "chronicle_replication_chain"

Hi, there is an issue when building database for PostgreSQL v9.6.7.

Here is the output:

$ php bin/make-tables.php
/var/www/public/workspace/chronicle/sql/pgsql/00-local.sql
/var/www/public/workspace/chronicle/sql/pgsql/01-remote.sql
PHP Fatal error:  Uncaught PDOException: SQLSTATE[42830]: Invalid foreign key: 7 ERROR:  there is no unique constraint matching given keys for referenced table "chronicle_replication_chain" in /var/www/public/workspace/chronicle/vendor/paragonie/easydb/src/EasyDB.php:1329
Stack trace:
#0 /var/www/public/workspace/chronicle/vendor/paragonie/easydb/src/EasyDB.php(1329): PDO->query('CREATE TABLE ch...')
#1 /var/www/public/workspace/chronicle/bin/make-tables.php(125): ParagonIE\EasyDB\EasyDB->query('CREATE TABLE ch...')
#2 {main}
  thrown in /var/www/public/workspace/chronicle/vendor/paragonie/easydb/src/EasyDB.php on line 1329

Thanks

PHP Client Library

Is there a PHP client library yet, like something that lets you interact with a chronicle server by calling functions instead of creating POST requests yourself?

[Feature Request] Extent Travis tests to cover all databases

Hi,

I noticed that the Chronicle is tested well on SQLite and maybe some on MySQL. But the test not exists to cover all these databases at once. I'm thinking to extend Travis to cover all the others because there are many many features will be added and need to be tested. So, we can push development further with confidence. The background is ready after merge this #49.

Thanks

[ISSUE] BLOB/TEXT column 'publicid' used in key specification without a key length

Hi,

I setup MySQL database for Chronicle and I have an issue with this line:

CREATE INDEX chronicle_clients_clientid_idx ON chronicle_clients(publicid);

The error:

#1170 - BLOB/TEXT column 'publicid' used in key specification without a key length

Database details:

Server: Localhost via UNIX socket
Server type: MySQL
Server version: 5.6.41-cll-lve - MySQL Community Server (GPL)
Protocol version: 10
User: cpses_xxxxxxxxxxxx@localhost
Server charset: UTF-8 Unicode (utf8)

Thanks

FK constraints and insertion of the first record

This commit introduced FK constraints:

080f251

However, when the first record is inserted the value of prevhash is NULL whereas currhash is an actual Blakechain hash. Given the introduced constraints the insertion of the first record will fail (tested on Postgres) thus preventing chain initialisation entirely.

ISSUE: No client header provided

Hi,

I did setup a two Chronicle instances which are Chronicle-A and Chronicle-B. I generated keypairs with php bin/keygin.php at Chronicle-A, then I took public key and create a new client with php bin/create-client.php at Chronicle-B which gave me a success result.

➜  php bin/create-client.php --publickey="N1DIRAN2XpXaIJpFx2IpDQpqF4j0bkGDhkmlNBI_NHU=" --comment="point-BB"
	Client (VeVGBO9gThq_eTzCbAR3vgrhEHrUnRqL) created successfully!

I try to test publish some data with the following code:

<?php

$root = \dirname(__DIR__);
/** @psalm-suppress UnresolvableInclude */
require_once $root . '/cli-autoload.php';

use GuzzleHttp\Client;
use ParagonIE\Sapient\Sapient;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\Sapient\Adapter\Guzzle as GuzzleAdapter;
use ParagonIE\Sapient\CryptographyKeys\SigningPublicKey;
use ParagonIE\Sapient\CryptographyKeys\SigningSecretKey;
use ParagonIE\Sapient\Exception\InvalidMessageException;

$http = new Client([
    'base_uri' => 'http://localhost:8080'
]);
$sapient = new Sapient(new GuzzleAdapter($http));

// Keys
$clientSigningKey = new SigningSecretKey(
    Base64UrlSafe::decode(
        'JblJ6oEbqA8pBQKbwX_gSb7wCP85--C9ANyRU-eYGUM3UMhEA3ZeldogmkXHYikNCmoXiPRuQYOGSaU0Ej80dQ=='
    )
);
$serverPublicKey = new SigningPublicKey(
    Base64UrlSafe::decode(
        'N1DIRAN2XpXaIJpFx2IpDQpqF4j0bkGDhkmlNBI_NHU='
    )
);

// We use an array to define our message
$myMessage = [
    'date' => (new DateTime)->format(DateTime::ATOM),
    'body' => [
        'test' => 'hello world!'        
    ]
];

// Create the signed request:
$request = $sapient->createSignedJsonRequest(
    'POST',
     '/chronicle/publish',
     $myMessage,
     $clientSigningKey
);

$response = $http->send($request);
try {
    /** @var array $verifiedResponse */
    $verifiedResponse = $sapient->decodeSignedJsonResponse(
        $response,
        $serverPublicKey
    );
} catch (InvalidMessageException $ex) {
    echo $ex->getMessage();
    // \http_response_code(500);
    exit;
}

Then, I received this error:

Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `POST http://localhost:8080/chronicle/publish` resulted in a `403 Forbidden` response:
{
    "version": "1.0.x",
    "datetime": "2018-07-06T19:57:36+00:00",
    "status": "ERROR",
    "message": "No client  (truncated...)
in /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113
Stack trace:
#0 /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/guzzle/src/Middleware.php(66): GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Psr7\Request), Object(GuzzleHttp\Psr7\Response))
#1 /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/promises/src/Promise.php(203): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response))
#2 /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/promises/src/Promise.php(156): GuzzleHttp\Promise\Promise::callHandler(1, Object(GuzzleHttp\Psr7\Response), Array)
#3 /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/promises/src/TaskQueue.php(47): Guzzl in /Users/vzool/Workspace/chronicleA/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php on line 113

After I dig more into Publish Handler I found the truncated message, which is here:

No client header provided 

What I did miss here?

Thanks

tflori/getopt-php is abandoned

I'm sure this is on your radar already....

Package tflori/getopt-php is abandoned, you should avoid using it. Use ulrichsg/getopt-php instead.

How to verify contents response?

This project seems interesting and potentially something I'd like to use for a project, however not entirely sure how the design works on the verification side.

I installed the Chronicle and a replica. How can the clients be sure that the contents returned from a Chronicle are intact? Do you have an pseudo code example of that?

My understanding is that you'd query multiple replicas and compare the contents response? But I feel like I'm missing something.

For example, is it required to compare the contents field against the currhash; if so how may the client compute that hash? Or is this only done as part of the Chronicle replication process?

Invalid identifier: Invalid characters supplied.

This was reported last year in #40 but that was related to scheduled tasks. Today I did a fresh install on Ubuntu 18.04 with PHP 7.3 and MariaDB 10.4.7 and am getting it with client creation.

When running:
php bin/create-client.php -p "XXXXXX" -c "Test"

The below is thrown:

PHP Fatal error:  Uncaught ParagonIE\EasyDB\Exception\InvalidIdentifier: Invalid identifier: Invalid characters supplied. in /home/chrishaas/chronicle/vendor/paragonie/easydb/src/EasyDB.php:297
Stack trace:
#0 /home/chrishaas/chronicle/vendor/paragonie/easydb/src/EasyDB.php(870): ParagonIE\EasyDB\EasyDB->escapeIdentifier('`chronicle_clie...')
#1 /home/chrishaas/chronicle/vendor/paragonie/easydb/src/EasyDB.php(519): ParagonIE\EasyDB\EasyDB->buildInsertQueryBoolSafe('`chronicle_clie...', Array)
#2 /home/chrishaas/chronicle/bin/create-client.php(126): ParagonIE\EasyDB\EasyDB->insert('`chronicle_clie...', Array)
#3 {main}
  thrown in /home/chrishaas/chronicle/vendor/paragonie/easydb/src/EasyDB.php on line 297

MariaDB version:

mysql  Ver 15.1 Distrib 10.4.7-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

PHP Version:

PHP 7.3.8-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Aug  7 2019 09:52:12) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.8, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.8-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies```

Replica Mode, Auditing Utility

  • It should be easy to setup a Chronicle instance that mirrors another instance, given its URL and public key.
  • It should be possible to compare two or more hash chains and identify divergence. (Standalone tool or bundled?)
    • This tool should be simple and straightforward to use.

SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value

I started testing out now after fixing database creation for MySQL. So, error show up when publish data:

Type: PDOException
Code: 22007
Message: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2018-10-19T21:18:39+00:00' for column 'created' at row 1
File: /home/vagrant/code/my-chronicle/vendor/paragonie/easydb/src/EasyDB.php
Line: 846
Trace: #0 /home/vagrant/code/my-chronicle/vendor/paragonie/easydb/src/EasyDB.php(846): PDOStatement->execute(Array)
#1 /home/vagrant/code/my-chronicle/vendor/paragonie/easydb/src/EasyDB.php(521): ParagonIE\EasyDB\EasyDB->safeQuery('INSERT INTO `ch...', Array, 4, true)
#2 /home/vagrant/code/my-chronicle/src/Chronicle/Chronicle.php(114): ParagonIE\EasyDB\EasyDB->insert('chronicle_chain', Array)
#3 /home/vagrant/code/my-chronicle/src/Chronicle/Handlers/Publish.php(92): ParagonIE\Chronicle\Chronicle::extendBlakechain('{\n    "date": "...', 'w8J2tTFL5THh4P_...', Object(ParagonIE\Sapient\CryptographyKeys\SigningPublicKey))
#4 [internal function]: ParagonIE\Chronicle\Handlers\Publish->__invoke(Object(Slim\Http\Request), Ob" while reading response header from upstream, client: 192.168.10.1, server: chronicle.local, request: "POST /chronicle/publish HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "chronicle.local"

More investigation will going on tomorrow morning, if God's will. ^_^

[Feature Request] Output full result like `lookup` for `/chronicle/lasthash` endpoint

Hi, this /chronicle/lasthash endpoint usually is used in one of the two steps to get the last hash with data.

So, I think if we just return all the record data for this API then we'll decrease the number of steps by 50%.

But, if there is a specific use case that I'm not aware of about the current design, then we can create a new API /chronicle/last.

Thanks

[Use Case] Multiple Chains - Company Agreements

Hi,

I have an idea to use chronicle in which is any company has many agreements with their customers, agreements like (TOS, privacy & many more).
The company is a very transparent company with their customers and it does want every customer to agree on every change for their business model.
After some time design some considerations I come up with this structure:

$block = [
    [
        'type' => 'tos',
        'hash' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
        'terms' => ' ... ',
        'effective_at' => '2019-06-09 00:00:00',
        'functions' => [
            'deprecated' => [
                // ..
            ],
            'current' => [
                // ..
            ],
            'new' => [
                // ..
            ],
        ],
    ],
    [
        'type' => 'privacy',
        'hash' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
        'terms' => ' ... ',
        'effective_at' => '2018-06-09 00:00:00',
        'functions' => [
            'deprecated' => [
                // ..
            ],
            'current' => [
                // ..
            ],
            'new' => [
                // ..
            ],
        ],
    ],

    // ...
];

But, If just I want to update the privacy terms I will need to duplicate TOS and many others with it in order to be keep tracking last version for all agreements at /chronicle/lasthash , I feel current chronicle does not provide multiple chains, subjects or networks
So, I think it will be a better if add the support for multiple networks, something like this /chronicle/{network}/lasthash.
I prefer subject term over the network, because the url will be more fluent:

  • /chronicle/tos/lasthash
  • /chronicle/privacy/lasthash

The update to APIs will be:

[
	{
		uri: "/chronicle/{subject}/lasthash",
		description: "Get information about the latest entry in this Chronicle at custom subject"
	},
	{
		uri: "/chronicle/lasthash",
		description: "Get information about the latest entry in this Chronicle at main subject"
	},
	{
		uri: "/chronicle/lookup/{subject}/{hash}",
		description: "Lookup the information for the given hash at custom subject"
	},
	{
		uri: "/chronicle/lookup/{hash}",
		description: "Lookup the information for the given hash at main subject"
	},
	{
		uri: "/chronicle/since/{hash}",
		description: "List all new entries since a given hash at custom subject"
	},
	{
		uri: "/chronicle/since/{subject}/{hash}",
		description: "List all new entries since a given hash at main subject"
	},
	{
		uri: "/chronicle/{subject}/export",
		description: "Export the entire Chronicle at custom subject"
	},
	{
		uri: "/chronicle/export",
		description: "Export the entire Chronicle at main subject"
	},
	{
		uri: "/chronicle/replica",
		description: "List of Chronicles being replicated onto this one (and other options)"
	},
	{
		uri: "/chronicle",
		description: "API method description"
	}
]

If chronicle will offer something like this, then it can be used in many other cases like:

  • News agency /chronicle/new-york/lasthash as a news feed.
  • Applications development Changelog /chronicle/changelog/lasthash.
  • Blog storage.

Any suggestions are very welcome. <3

Instance Deployment - One-Click Setup

Whether this means selling AMIs on the AWS Marketplace (like we do with CMS Airship), or partnering with another provider (Digital Ocean, perhaps?).

If we don't go the AMI route, this issue is up for grabs.

Enhancement suggestion: Cloud support

Hi,

I realise its a possibly little "easier said than done" in terms of complexity. But in terms of enhancing the replication capability of chronicle, it might be nice to see cloud support.

Support for "cheap & simple" variants such as AWS Dynamo or Azure Tables could provide a nice replication option.

PHP Fatal error: Uncaught Error: Call to a member function escapeIdentifier() on null

Hi, I want to create a new client but I faced this issue.

➜  chronicle git:(master) php bin/create-client.php -p "xml6UZZdha1ypeTbcFWmG-CWbgz7zxjDq6DpPdrsDVI=" --administrator
PHP Fatal error:  Uncaught Error: Call to a member function escapeIdentifier() on null in /home/vzool/Workspace/chronicle/src/Chronicle/Chronicle.php:67
Stack trace:
#0 /home/vzool/Workspace/chronicle/bin/create-client.php(115): ParagonIE\Chronicle\Chronicle::getTableName('clients')
#1 {main}
  thrown in /home/vzool/Workspace/chronicle/src/Chronicle/Chronicle.php on line 67

PHP version information:

PHP 7.2.5 (cli) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

I used SQLite database.

Thanks

Replication is failing

Hi, cool project!

I installed it and seems to work fine for the most part, but I am having issues with the replication.

I follow the steps in the docs: installed the first Chronicle instance, configured it up to MySQL, built tables and such. Then added a client and published some data to it.

Then I created a 2nd one, ran bin/replicate.php with a target of http://127.0.0.1:8080/chronicle and the first Chronicle's pub key. This seems to work well too, and adds an entry to the chronicle_replication_sources.

However, the secondary Chronicle does not seem to be replicating the source. I modified the "scheduled-attestation": to 360 seconds but not seeing any hashes on the secondary instance. I tried to execute the scheduled-tasks.php script and got the following error:

Fatal error: Uncaught ParagonIE\Chronicle\Exception\SecurityViolation: Invalid summary hash. Expected Pxqeejbjl-mAipyhtIDevQNmdpBHMN_-XBCZ6sQ1y7c=, calculated bpqrzUNnTsNg4aSHcBXOnn-qJzyUYB62MJtCSORr6bM= 

in src\Chronicle\Process\Replicate.php:203

I also truncated the chains and tried to replicate again, but no luck.

Do you have any idea why this might be?

[Feature Request] API for available instances

Hi, I'm looking forward to an API that lists all public instances in the chronicle app, then this will lead us to hide other instances for some use cases. By that in mind I suggest to update local/settings.json to support this feature like the following:

{
  ...

  "instances": {
    "": {
      "name": "",
      "public": true,
      "desc": "Default public instance"
    }
  },

  ...
}

I mean by public if set to false is just to hide the instance in the suggested API result. Thanks

Making Replication More Useful -- Opinions Sought

Currently, there are two features that can be used to make attacking the immutability of a Chronicle very difficult:

  1. Cross-signing, which pushes the latest currhash and summaryhash onto a peer's Chronicle.
  2. Replication, which allows a Chronicle to archive many other Chronicles' contents in a separate table. (Each new record is validated before copying.)

This opens the door to several possibilities:

  1. Provide a public API which lists which Chronicles are replicated and lets others query the replicated data. (Not necessarily desirable. Maybe make it a configuration option later?)
  2. Provide a command line utility for remotely verifying the integrity of a replicated Chronicle. (Possibly include an alerting mechanism in case something is amiss?)
  3. Scheduled attestation of other Chronicles' integrity.

A scheduled attestation means your Chronicle will occasionally publish the latest currhash and summaryhash for a replicated Chronicle onto its own history, which may force a cross-sign.

The purpose of replication is to provide a second opinion in case the replicated Chronicle is compromised but yours is not. If we go with scheduled attestation, that will strengthen the resilience. If we expose replicated data, we can strengthen the availability of a Chronicle's contents to resist targeted DoS attacks against the central server.

Which features should be implemented? Please comment or use Github reactions to vote.

  • 👍 for the public API (allows mirroring)
  • 😆 for the command line utility
  • 🎉 for the scheduled attestation
  • 👎 for none of the above (this is the "no feature bloat" option)

Replication failing

I'm back :)

The replication is failing with the folowing error:

PHP Notice:  Undefined index: summary in /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php on line 183
PHP Warning:  hash_equals(): Expected known_string to be a string, null given in /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php on line 183
PHP Notice:  Undefined index: summary in /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php on line 186
PHP Fatal error:  Uncaught ParagonIE\Chronicle\Exception\SecurityViolation: Invalid summary hash. Expected , calculated g_uhhZBFE4iP-k9rPx_TyzdJz6NYfgZYQetvThhAo8M= in /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php:185
Stack trace:
#0 /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php(116): ParagonIE\Chronicle\Process\Replicate->appendToChain(Array)
#1 /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Scheduled.php(129): ParagonIE\Chronicle\Process\Replicate->replicate()
#2 /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Scheduled.php(86): ParagonIE\Chronicle\Scheduled->doReplication()
#3 /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Scheduled.php(60): ParagonIE\Chronicle\Scheduled->runAll()
#4 /var/www/vhosts/example.com/chronicle.example.com/bin/scheduled-tasks.php(36): ParagonIE\Chronicle\Scheduled->run()
#5 {main}
  thrown in /var/www/vhosts/example.com/chronicle.example.com/src/Chronicle/Process/Replicate.php on line 185

Possibly because of a missing signature in the second to last entry in the chain?

Replicating: https://php-chronicle.pie-hosted.com/chronicle/export

Uncaught ParagonIE\EasyDB\Exception\ConstructorFailed: Could not create a PDO connection

Sorry, but am I missing something stupid here ?

Fatal error: Uncaught ParagonIE\EasyDB\Exception\ConstructorFailed: Could not create a PDO connection. Please check your username and password. in /blah/chronicle/vendor/paragonie/easydb/src/Factory.php:65

local/settings.json is as per your example:

    "database": {
        "dsn": "pgsql:host=myhost;port=5432;dbname=mydb",
        "username": "myuser",
        "password": "mypass"
    }

and....

psql -U myuser -d mydb -h myhost -W

works just fine (i.e. pg_hba is correctly setup and reloaded, I can manipulate stuff as the user etc. ), and....

No errors are recorded in the postgres logs.

and .....

I know postgres connections work just fine from this machine because I've got other PHP stuff on there accessing the same postgres server. So there's no firewalls or other stuff going on.

This is postgres 9.6.8 and php 7.2.4.

Code Review

Do not pass around $app

Your route defintions are not ideal.

$app->group('/chronicle', function () use ($app) {
    $app->post('/publish', new Register($app))
        ->add(new CheckAdminSignature());
    $app->post('/publish', new Revoke($app))
        ->add(new CheckAdminSignature());
    $app->post('/publish', new Publish($app))
        ->add(new CheckClientSignature());
    $app->get('/lasthash', new Lookup($app, 'lasthash'));
    $app->get('/lookup/[{hash}]', new Lookup($app, 'hash'));
    $app->get('/since/[{hash}]', new Lookup($app, 'since'));
    $app->get('/export', new Lookup($app, 'export'));
});
  1. When inside the group the router is bound to the anom function allowing you to use $this instead of currying $app

  2. you can use an empty route group to apply middleware to multiple things

  3. With your current routes every request you are creating each of those Handlers when you do not need to. You may register handlers via a String in the container and then use the container key in the 2nd argument of the http method.

  4. Furthermore, 3 applies to middleware as well.

//Routes
$app->group('/chronicle', function () {
    $this->group('', function () {
        $this->post('/publish', Register::class);    //This is a bug <---
        $this->post('/publish', Revoke::class;      //This is a bug <---
        $this->post('/publish', Publish::class); 
    })->add(CheckAdminSignature::class);

    $this->get('/lasthash', 'lookup.lasthash');
    $this->get('/lookup/[{hash}]', 'lookup.hash');
    $this->get('/since/[{hash}]', 'lookup.since');
    $this->get('/export', 'lookup.export');
});

//Container Definitions
$container[CheckAdminSignature::class] = function ($c) { ... };
$container[Register::class] = function ($c) { ... };
$container[Revoke::class] = function ($c) { ... };
$container[Publish::class] = function ($c) { ... };
$container['lookup.lasthash'] = function ($c) { ... };
$container['lookup.hash'] = function ($c) { ... };
$container['lookup.since'] = function ($c) { ... };
$container['lookup.export'] = function ($c) { ... };

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.