Issues (32)

src/Backend/Chainpoint/Service.php (5 issues)

1
<?php
2
3
/**
4
 * @author  Russell Michell 2018 <[email protected]>
5
 * @package silverstripe-verifiable
6
 */
7
8
namespace PhpTek\Verifiable\Backend\Chainpoint;
9
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\Core\Injector\Injectable;
12
use SilverStripe\Core\Config\Configurable;
13
use PhpTek\Verifiable\Backend\GatewayProvider;
14
use PhpTek\Verifiable\Backend\ServiceProvider;
15
use PhpTek\Verifiable\Backend\Chainpoint\Gateway;
16
17
/**
18
 * Service class that works as an intermediary between any data model and the
19
 * currently selected Merkle Tree backend gateway.
20
 *
21
 * @todo There should be only one service. The gateway is the part that changes
22
 *       between backend implementations.
23
 */
24
class Service implements ServiceProvider
25
{
26
    use Injectable;
27
    use Configurable;
28
29
    /**
30
     * @var GatewayProvider
31
     */
32
    protected $backend;
33
34
    /**
35
     *
36
     * @var array
37
     */
38
    protected $extra = [];
39
40
    /**
41
     * @return void
42
     */
43
    public function __construct()
44
    {
45
        $this->setGateway();
46
    }
47
48
    /**
49
     * @return string
50
     */
51
    public function name() : string
52
    {
53
        return $this->getGateway()->name();
54
    }
55
56
    /**
57
     * Wrapper around all gateway methods.
58
     *
59
     * @param  string $method The name of the method to call
60
     * @param  mixed  $arg    The argument to pass to $method
61
     * @return mixed
62
     * @throws InvalidArgumentException
63
     */
64
    public function call($method, $arg)
65
    {
66
        if (!method_exists($this, $method)) {
67
            throw new \InvalidArgumentException("$method doesn't exist.");
68
        }
69
70
        $this->gateway->setDiscoveredNodes($this->getExtra());
71
72
        return $this->$method($arg);
73
    }
74
75
    /**
76
     * Write a hash of data as per the "verifiable_fields" config static on each
77
     * {@link DataObject}.
78
     *
79
     * @param  array $data
80
     * @return mixed The result of this call to the backend.
81
     */
82
    protected function write(array $data)
83
    {
84
        return $this->gateway->hashes([$this->hash($data)]);
85
    }
86
87
    /**
88
     * Fetch a chainpoint proof for the passed $uuid.
89
     *
90
     * @param  mixed string | array $uuid
91
     * @return string The JSON-LD chainpoint proof.
92
     */
93
    protected function read($uuid) : string
94
    {
95
        if (is_array($uuid)) {
96
            return $this->gateway->proofs(array_unique($uuid));
97
        }
98
99
        return $this->gateway->proofs($uuid);
100
    }
101
102
    /**
103
     * Verify the given JSON-LD chainpoint proof against the backend.
104
     *
105
     * @param  string $proof A JSON-LD chainpoint proof.
106
     * @return mixed
107
     */
108
    protected function verify(string $proof)
109
    {
110
        return $this->gateway->verify($proof);
111
    }
112
113
    /**
114
     * Set some arbitrary data onto the service. Used as a way of acting as
115
     * an intermediary or broker between DataObjects and the backend.
116
     *
117
     * @param  array $extra
118
     * @return VerifiableService
0 ignored issues
show
The type PhpTek\Verifiable\Backen...point\VerifiableService was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
119
     */
120
    public function setExtra(array $extra = [])
121
    {
122
        if (!$extra) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extra of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
123
            $this->gateway->setDiscoveredNodes();
124
            $this->extra = $this->gateway->getDiscoveredNodes();
125
        } else {
126
            $this->extra = $extra;
127
        }
128
129
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PhpTek\Verifiable\Backend\Chainpoint\Service which is incompatible with the documented return type PhpTek\Verifiable\Backen...point\VerifiableService.
Loading history...
130
    }
131
132
    /**
133
     * Return arbitrary data set to this service.
134
     *
135
     * @return array
136
     */
137
    public function getExtra()
138
    {
139
        return $this->extra;
140
    }
141
142
    /**
143
     * Set, configure and return a new Merkle Tree storage backend.
144
     *
145
     * @param  GatewayProvider   $provider Optional manually passed backend.
146
     * @return VerifiableService
147
     */
148
    public function setGateway(GatewayProvider $provider = null)
149
    {
150
        if ($provider) {
151
            $this->gateway = $provider;
0 ignored issues
show
Bug Best Practice introduced by
The property gateway does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
152
153
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PhpTek\Verifiable\Backend\Chainpoint\Service which is incompatible with the documented return type PhpTek\Verifiable\Backen...point\VerifiableService.
Loading history...
154
        }
155
156
        $this->gateway = Injector::inst()->create(Gateway::class);
157
    }
158
159
    /**
160
     * @return GatewayProvider
161
     */
162
    public function getGateway()
163
    {
164
        return $this->gateway;
165
    }
166
167
    /**
168
     * Hashes the data passed as the $data param.
169
     *
170
     * @param  array  $data An array of data who's values should be hashed.
171
     * @return string       The resulting hashed data.
172
     */
173
    public function hash(array $data) : string
174
    {
175
        $func = $this->gateway->hashFunc();
176
        $text = serialize($data);
177
178
        return hash($func, $text, false);
179
    }
180
}
181