Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Crypt
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 3
42
0.00% covered (danger)
0.00%
0 / 1
 encrypt
n/a
0 / 0
n/a
0 / 0
0
 decrypt
n/a
0 / 0
n/a
0 / 0
0
 cleanup
n/a
0 / 0
n/a
0 / 0
0
 canDecrypt
n/a
0 / 0
n/a
0 / 0
0
 getCryptTypes
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 factory
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getCreateDescriptors
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getTallyDescriptors
n/a
0 / 0
n/a
0 / 0
0
 updateTallyContext
n/a
0 / 0
n/a
0 / 0
0
 updateDbForTallyJob
n/a
0 / 0
n/a
0 / 0
0
 cleanupDbForTallyJob
n/a
0 / 0
n/a
0 / 0
0
1<?php
2
3namespace MediaWiki\Extension\SecurePoll\Crypt;
4
5use InvalidArgumentException;
6use MediaWiki\Extension\SecurePoll\Context;
7use MediaWiki\Extension\SecurePoll\Entities\Election;
8use MediaWiki\Status\Status;
9use Wikimedia\Rdbms\IDatabase;
10
11/**
12 * Cryptography module
13 */
14abstract class Crypt {
15    /**
16     * Encrypt some data. When successful, the value member of the Status object
17     * will contain the encrypted record.
18     * @param string $record
19     * @return Status
20     */
21    abstract public function encrypt( $record );
22
23    /**
24     * Decrypt some data. When successful, the value member of the Status object
25     * will contain the encrypted record.
26     * @param string $record
27     * @return Status
28     */
29    abstract public function decrypt( $record );
30
31    /**
32     * @internal Generic clean up function. Internal functions can call this to clean up
33     * after themselves or callers can manually clean up after processing.
34     * Ideally, functions would be self-contained but due to performance
35     * constraints, this is not always possible. In those cases, the caller
36     * should be responsible for cleanup.
37     */
38    abstract public function cleanup();
39
40    /**
41     * Returns true if the object can decrypt data, false otherwise.
42     */
43    abstract public function canDecrypt();
44
45    /**
46     * Returns a list of supported Crypt subclasses for encrypting votes.
47     *
48     * @return array<string,class-string<Crypt>|false>
49     */
50    public static function getCryptTypes() {
51        $cryptTypes = [
52            'none' => false
53        ];
54
55        if ( extension_loaded( 'openssl' ) ) {
56            $cryptTypes['openssl'] = OpenSslCrypt::class;
57        }
58
59        return $cryptTypes;
60    }
61
62    /**
63     * Create an encryption object of the given type.
64     * @param Context $context
65     * @param string $type
66     * @param Election $election
67     * @return self|false False when encryption type is set to "none"
68     */
69    public static function factory( $context, $type, $election ) {
70        $cryptTypes = self::getCryptTypes();
71
72        if ( !isset( $cryptTypes[$type] ) ) {
73            throw new InvalidArgumentException( "Invalid crypt type: $type" );
74        }
75        $class = $cryptTypes[$type];
76
77        return $class ? new $class( $context, $election ) : false;
78    }
79
80    /**
81     * Return descriptors for any properties this type requires for poll
82     * creation, for the election, questions, and options.
83     *
84     * The returned array should have three keys, "election", "question", and
85     * "option", each mapping to an array of HTMLForm descriptors.
86     *
87     * The descriptors should have an additional key, "SecurePoll_type", with
88     * the value being "property" or "message".
89     *
90     * @return array
91     */
92    public static function getCreateDescriptors() {
93        return [
94            'election' => [],
95            'question' => [],
96            'option' => [],
97        ];
98    }
99
100    /**
101     * Return descriptors for any properties this type requires for poll
102     * tallying.
103     *
104     * @return array
105     */
106    abstract public function getTallyDescriptors(): array;
107
108    /**
109     * Update the given context with any information needed for tallying.
110     *
111     * This allows some information, e.g. private keys, to be used for a
112     * single request and not added to the database.
113     *
114     * @param Context $context
115     * @param array $data
116     */
117    abstract public function updateTallyContext( Context $context, array $data ): void;
118
119    /**
120     * Update the database with any information needed for tallying via a job.
121     *
122     * This may include adding private keys to the database. While not ideal,
123     * this is nothing new in SecurePoll. It should only be done once an
124     * election is finished, and should be cleaned up.
125     *
126     * @see Crypt::cleanupDbForTallyJob
127     * @param int $electionId
128     * @param IDatabase $dbw
129     * @param array $data
130     */
131    abstract public function updateDbForTallyJob(
132        int $electionId,
133        IDatabase $dbw,
134        array $data
135    ): void;
136
137    /**
138     * Clean up the database after tallying via a job.
139     *
140     * @see Crypt::updateDbForTallyJob
141     * @param int $electionId
142     * @param IDatabase $dbw
143     */
144    abstract public function cleanupDbForTallyJob( int $electionId, IDatabase $dbw ): void;
145}