Issues (9)

src/controllers/AbstractUpsertController.php (4 issues)

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: dsmrt
5
 * Date: 2/7/18
6
 * Time: 11:16 PM
7
 */
8
9
namespace flipbox\keychain\controllers;
10
11
use Craft;
12
use craft\web\Request;
13
use flipbox\keychain\controllers\cp\AbstractController;
14
use flipbox\keychain\controllers\cp\view\EditController;
15
use flipbox\keychain\KeyChain;
16
use flipbox\keychain\keypair\Byok;
17
use flipbox\keychain\keypair\OpenSSL;
18
use flipbox\keychain\records\KeyChainRecord;
19
20
abstract class AbstractUpsertController extends AbstractController
21
{
22
    /**
23
     * @return \yii\web\Response
24
     * @throws \yii\web\BadRequestHttpException
25
     */
26
    public function actionIndex()
27
    {
28
        $this->requireAdmin(false);
29
        $this->requirePostRequest();
30
31
        /** @var Request $request */
32
        $request = Craft::$app->request;
0 ignored issues
show
Documentation Bug introduced by
It seems like Craft::app->request can also be of type craft\web\Request. However, the property $request is declared as type craft\console\Request. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
33
        $id = $request->getBodyParam('identifier');
34
        if ($id) {
35
            /** @var KeyChainRecord $keypair */
36
            $keypair = KeyChainRecord::find()->where([
37
                'id' => $id,
38
            ])->one();
39
40
            if ($keypair->isEncrypted) {
41
                $keypair->getDecryptedKey();
42
            }
43
        } else {
44
            $keypair = (new Byok([
45
                'key'         => $request->getBodyParam('key'),
46
                'certificate' => $request->getBodyParam('certificate'),
47
                'description' => $request->getBodyParam('description'),
48
            ]))->create();
49
        }
50
51
        /**
52
         * Set is decrypted so we know that the key and cert value is raw.
53
         */
54
        $keypair->isDecrypted = true;
55
        Craft::configure($keypair, [
56
            'key'          => $request->getBodyParam('key'),
57
            'certificate'  => $request->getBodyParam('certificate'),
58
            'description'  => $request->getBodyParam('description'),
59
            'isEncrypted'  => $request->getBodyParam('isEncrypted') ?: false,
60
            'pluginHandle' => $request->getBodyParam('pluginHandle'),
61
        ]);
62
        /**
63
         * Make sure enabled as a value
64
         */
65
        if ($keypair->enabled === null) {
66
            $keypair->enabled = true;
67
        }
68
69
70
        if (KeyChain::getInstance()->getService()->save($keypair)) {
71
            Craft::$app->getSession()->setNotice(Craft::t('keychain', 'Key pair saved.'));
72
        } else {
73
            Craft::$app->getSession()->setError(Craft::t('keychain', 'Key pair didn\'t save.'));
74
            return $this->renderTemplate(
75
                EditController::TEMPLATE_INDEX,
76
                array_merge(
77
                    $this->getBaseVariables(),
78
                    [
79
                        'keypair' => $keypair,
80
                    ]
81
                )
82
            );
83
        }
84
85
        return $this->redirectToPostedUrl();
86
    }
87
88
    /**
89
     * @return \yii\web\Response
90
     * @throws \yii\web\BadRequestHttpException
91
     */
92
    public function actionOpenssl()
93
    {
94
        $this->requireAdmin(false);
95
        $this->requirePostRequest();
96
97
        /** @var Request $request */
98
        $request = Craft::$app->request;
0 ignored issues
show
Documentation Bug introduced by
It seems like Craft::app->request can also be of type craft\web\Request. However, the property $request is declared as type craft\console\Request. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
99
100
        $keychainRecord = (new OpenSSL([
101
            'description'            => $request->getBodyParam('description'),
102
            'countryName'            => $request->getBodyParam('countryName'),
103
            'stateOrProvinceName'    => $request->getBodyParam('stateOrProvinceName'),
104
            'localityName'           => $request->getBodyParam('localityName'),
105
            'organizationName'       => $request->getBodyParam('organizationName'),
106
            'organizationalUnitName' => $request->getBodyParam('organizationalUnitName'),
107
            'commonName'             => $request->getBodyParam('commonName'),
108
            'emailAddress'           => $request->getBodyParam('emailAddress'),
109
        ]))->create();
110
111
        Craft::configure($keychainRecord, [
112
            'enabled'      => $request->getBodyParam('enabled') ?: false,
113
            'isEncrypted'  => $request->getBodyParam('isEncrypted') ?: false,
114
            'pluginHandle' => $request->getBodyParam('plugin'),
115
        ]);
116
        $keychainRecord->isDecrypted = true;
117
118
        if (KeyChain::getInstance()->getService()->save($keychainRecord)) {
119
            Craft::$app->getSession()->setNotice(Craft::t('keychain', 'Key pair saved.'));
120
        } else {
121
            Craft::$app->getSession()->setError(Craft::t('keychain', 'Key pair didn\'t save.'));
122
            return $this->renderTemplate(
123
                EditController::TEMPLATE_INDEX,
124
                array_merge(
125
                    $this->getBaseVariables(),
126
                    [
127
                        'keypair' => $keychainRecord,
128
                    ]
129
                )
130
            );
131
        }
132
133
        return $this->redirectToPostedUrl();
134
    }
135
136
    /**
137
     * @return \yii\web\Response
138
     * @throws \yii\web\BadRequestHttpException
139
     * @throws \yii\web\ForbiddenHttpException
140
     */
141
    public function actionGenerateOpenssl()
142
    {
143
        $this->requireAdmin(false);
144
        $this->requirePostRequest();
145
        $config = [];
146
        if ($plugin = Craft::$app->request->getParam('plugin')) {
147
            $config = [
148
                'pluginHandle' => $plugin,
149
            ];
150
        }
151
152
        /** @var KeyChainRecord $keyPair */
153
        $keyPair = KeyChain::getInstance()->getService()->generateOpenssl($config);
154
155
        if (Craft::$app->request->isAjax) {
156
            return $this->asJson($keyPair->toArray());
157
        }
158
159
        if (! $keyPair->hasErrors()) {
160
            Craft::$app->getSession()->setNotice(Craft::t('keychain', 'Key pair saved.'));
161
        } else {
162
            Craft::$app->getSession()->setError(Craft::t('keychain', 'Key pair didn\'t save.'));
163
            return $this->renderTemplate(
164
                EditController::TEMPLATE_INDEX,
165
                array_merge(
166
                    $this->getBaseVariables(),
167
                    [
168
                        'keypair' => $keyPair,
169
                    ]
170
                )
171
            );
172
        }
173
174
        return $this->redirectToPostedUrl();
175
    }
176
177
178
    /**
179
     * @return \yii\web\Response
180
     * @throws \yii\web\BadRequestHttpException
181
     * @throws \yii\web\ForbiddenHttpException
182
     */
183
    public function actionChangeStatus()
184
    {
185
        $this->requireAdmin(false);
186
        $keypairId = Craft::$app->request->getRequiredBodyParam('identifier');
187
188
        $keychainRecord = KeyChainRecord::find()->where([
189
            'id' => $keypairId,
190
        ])->one();
191
192
        $keychainRecord->enabled = ! $keychainRecord->enabled;
193
194
        if (KeyChain::getInstance()->getService()->save($keychainRecord)) {
0 ignored issues
show
It seems like $keychainRecord can also be of type array and null; however, parameter $keyChainRecord of flipbox\keychain\services\KeyChainService::save() does only seem to accept flipbox\keychain\records\KeyChainRecord, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
        if (KeyChain::getInstance()->getService()->save(/** @scrutinizer ignore-type */ $keychainRecord)) {
Loading history...
195
            Craft::$app->getSession()->setNotice(Craft::t('keychain', 'Key pair saved.'));
196
        } else {
197
            Craft::$app->getSession()->setError(Craft::t('keychain', 'Key pair didn\'t save.'));
198
            return $this->renderTemplate(
199
                EditController::TEMPLATE_INDEX . '/openssl',
200
                array_merge(
201
                    $this->getBaseVariables(),
202
                    [
203
                        'keypair' => $keychainRecord,
204
                    ]
205
                )
206
            );
207
        }
208
209
        return $this->redirectToPostedUrl();
210
    }
211
212
    /**
213
     * @return \yii\web\Response
214
     * @throws \Throwable
215
     * @throws \yii\db\StaleObjectException
216
     * @throws \yii\web\BadRequestHttpException
217
     * @throws \yii\web\ForbiddenHttpException
218
     */
219
    public function actionDelete()
220
    {
221
        $this->requireAdmin(false);
222
        $keypairId = Craft::$app->request->getRequiredBodyParam('identifier');
223
224
        $keychainRecord = KeyChainRecord::find()->where([
225
            'id' => $keypairId,
226
        ])->one();
227
228
        if (false !== KeyChain::getInstance()->getService()->delete($keychainRecord)) {
0 ignored issues
show
It seems like $keychainRecord can also be of type array and null; however, parameter $keyChainRecord of flipbox\keychain\service...yChainService::delete() does only seem to accept flipbox\keychain\records\KeyChainRecord, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

228
        if (false !== KeyChain::getInstance()->getService()->delete(/** @scrutinizer ignore-type */ $keychainRecord)) {
Loading history...
229
            Craft::$app->getSession()->setNotice(Craft::t('keychain', 'Key pair deleted.'));
230
        } else {
231
            Craft::$app->getSession()->setError(Craft::t('keychain', 'Key pair didn\'t delete.'));
232
            return $this->renderTemplate(
233
                EditController::TEMPLATE_INDEX,
234
                array_merge(
235
                    $this->getBaseVariables(),
236
                    [
237
                        'keypair' => $keychainRecord,
238
                    ]
239
                )
240
            );
241
        }
242
243
        return $this->redirectToPostedUrl();
244
    }
245
}
246