Completed
Push — master ( 3260ca...0c0ec5 )
by Christian
02:12
created

CreateCommand   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 13
lcom 2
cbo 4
dl 0
loc 203
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 29 1
A inject() 0 17 1
A execute() 0 26 1
A activateToken() 0 16 3
A saveConsumer() 0 12 3
A createIntegration() 0 17 2
A grantPermissions() 0 8 2
1
<?php
2
3
namespace N98\Magento\Command\Integration;
4
5
use Magento\Framework\Exception\AlreadyExistsException;
6
use Magento\Framework\Exception\IntegrationException;
7
use Magento\Framework\Exception\LocalizedException;
8
use Magento\Integration\Model\Integration as IntegrationAlias;
9
use Magento\Integration\Model\Oauth\Consumer as ConsumerModel;
10
use Magento\Integration\Model\Oauth\Token;
11
use Magento\Integration\Model\ResourceModel\Oauth\Consumer;
12
use N98\Magento\Command\AbstractMagentoCommand;
13
use N98\Magento\Command\Integration\Renderer\TableRenderer as TableRenderer;
14
use Symfony\Component\Console\Exception\RuntimeException;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
20
/**
21
 * Class CreateCommand
22
 * @package N98\Magento\Command\Integration
23
 */
24
class CreateCommand extends AbstractMagentoCommand
25
{
26
    /**
27
     * @var \Magento\Integration\Model\IntegrationFactory
28
     */
29
    private $integrationFactory;
30
31
    /**
32
     * @var \Magento\Integration\Model\OauthService
33
     */
34
    private $oauthService;
35
36
    /**
37
     * @var \Magento\Integration\Model\AuthorizationService
38
     */
39
    private $authorizationService;
40
41
    /**
42
     * @var \Magento\Integration\Model\Oauth\TokenFactory
43
     */
44
    private $tokenFactory;
45
46
    /**
47
     * @var \Magento\Integration\Model\IntegrationService
48
     */
49
    private $integrationService;
50
51
    /**
52
     * @var Consumer
53
     */
54
    private $consumerResource;
55
56
    /**
57
     * @var \Magento\Integration\Model\ResourceModel\Oauth\Token
58
     */
59
    private $tokenResource;
60
61
    protected function configure()
62
    {
63
        $this
64
            ->setName('integration:create')
65
            ->addArgument('name', InputArgument::REQUIRED, 'Name of the integration')
66
            ->addArgument('email', InputArgument::REQUIRED, 'Email')
67
            ->addArgument('endpoint', InputArgument::REQUIRED, 'Endpoint URL')
68
            ->addOption('consumer-key', '', InputOption::VALUE_REQUIRED, 'Consumer Key (length 32 chars)')
69
            ->addOption('consumer-secret', '', InputOption::VALUE_REQUIRED, 'Consumer Secret (length 32 chars)')
70
            ->addOption('access-token', '', InputOption::VALUE_REQUIRED, 'Access-Token (length 32 chars)')
71
            ->addOption('access-token-secret', '', InputOption::VALUE_REQUIRED, 'Access-Token Secret (length 32 chars)')
72
            ->addOption('resource', 'r', InputOption::VALUE_IS_ARRAY|InputOption::VALUE_REQUIRED, 'Defines a granted ACL resource', [])
73
            ->setDescription('Create a new integration');
74
75
        $help = <<<HELP
76
Creates a new integration e.g. for 3rd party applications.
77
78
<info>Keys and Secets</info>
79
Keys and secrets are generated by Magento if not defined by specify options.
80
If key or a secret is defined manually, you must guarantee that this key or secret is at least 32 characters long
81
and unique in the system.
82
83
<info>Permissions</info>
84
If you do not specify ACL resources by resource option, the new integration will get ALL permissions.
85
To see a list of all available ACL resources you can run the <comment>config:data:acl</comment> command.
86
87
HELP;
88
        $this->setHelp($help);
89
    }
90
91
    public function inject(
92
        \Magento\Integration\Model\IntegrationFactory $integrationFactory,
93
        \Magento\Integration\Model\IntegrationService $integrationService,
94
        \Magento\Integration\Model\ResourceModel\Oauth\Consumer $consumerResource,
95
        \Magento\Integration\Model\OauthService $oauthService,
96
        \Magento\Integration\Model\AuthorizationService $authorizationService,
97
        \Magento\Integration\Model\Oauth\TokenFactory $tokenFactory,
98
        \Magento\Integration\Model\ResourceModel\Oauth\Token $tokenResource
99
    ) {
100
        $this->integrationFactory = $integrationFactory;
101
        $this->integrationService = $integrationService;
102
        $this->oauthService = $oauthService;
103
        $this->authorizationService = $authorizationService;
104
        $this->tokenFactory = $tokenFactory;
105
        $this->consumerResource = $consumerResource;
106
        $this->tokenResource = $tokenResource;
107
    }
108
109
    /**
110
     * @param \Symfony\Component\Console\Input\InputInterface $input
111
     * @param \Symfony\Component\Console\Output\OutputInterface $output
112
     * @return int|void
113
     * @throws \Exception
114
     */
115
    protected function execute(InputInterface $input, OutputInterface $output)
116
    {
117
        $integrationName = $input->getArgument('name');
118
        $integrationEmail = $this->getHelperSet()->get('parameter')->askEmail($input, $output);
119
        $integrationEndpoint = $input->getArgument('endpoint');
120
121
        $consumerKey = $input->getOption('consumer-key');
122
        $consumerSecret = $input->getOption('consumer-secret');
123
        $accessToken = $input->getOption('access-token');
124
        $accessTokenSecret = $input->getOption('access-token-secret');
125
126
        $grantedResources = $input->getOption('resource');
127
128
        $integrationModel = $this->createIntegration($integrationName, $integrationEmail, $integrationEndpoint);
129
        $consumerModel = $this->saveConsumer($integrationModel, $consumerKey, $consumerSecret);
130
        $this->grantPermissions($integrationModel, $grantedResources);
131
        $tokenModel = $this->activateToken($integrationModel, $accessToken, $accessTokenSecret);
132
133
        $table = new TableRenderer(
134
            $output,
135
            $integrationModel,
136
            $consumerModel,
137
            $tokenModel
138
        );
139
        $table->render();
140
    }
141
142
    /**
143
     * @param IntegrationAlias $integrationModel
144
     * @param $accessToken
145
     * @param $accessTokenSecret
146
     * @return Token
147
     * @throws AlreadyExistsException
148
     */
149
    private function activateToken(IntegrationAlias $integrationModel, $accessToken, $accessTokenSecret): Token
150
    {
151
        /** @var Token $tokenModel */
152
        $tokenModel = $this->tokenFactory->create();
153
        $tokenModel->createVerifierToken($integrationModel->getConsumerId());
154
        $tokenModel->setType(Token::TYPE_ACCESS);
155
156
        if ($accessToken !== null) {
157
            $tokenModel->setToken($accessToken);
158
        }
159
        if ($accessTokenSecret !== null) {
160
            $tokenModel->setSecret($accessTokenSecret);
161
        }
162
        $this->tokenResource->save($tokenModel);
163
        return $tokenModel;
164
    }
165
166
    /**
167
     * @param IntegrationAlias $integrationModel
168
     * @param $consumerKey
169
     * @param $consumerSecret
170
     * @return ConsumerModel
171
     * @throws AlreadyExistsException
172
     * @throws LocalizedException
173
     * @throws \Magento\Framework\Oauth\Exception
174
     */
175
    private function saveConsumer(IntegrationAlias $integrationModel, $consumerKey, $consumerSecret): ConsumerModel
176
    {
177
        $consumerModel = $this->oauthService->loadConsumer($integrationModel->getConsumerId());
178
        if ($consumerKey !== null) {
179
            $consumerModel->setKey($consumerKey);
180
        }
181
        if ($consumerSecret !== null) {
182
            $consumerModel->setSecret($consumerSecret);
183
        }
184
        $this->consumerResource->save($consumerModel);
185
        return $consumerModel;
186
    }
187
188
    /**
189
     * @param $integrationName
190
     * @param $integrationEmail
191
     * @param $integrationEndpoint
192
     * @return IntegrationAlias
193
     * @throws IntegrationException
194
     */
195
    private function createIntegration($integrationName, $integrationEmail, $integrationEndpoint): IntegrationAlias
196
    {
197
        $integrationModel = $this->integrationService->findByName($integrationName);
198
199
        if ($integrationModel->getId() > 0) {
200
            throw new RuntimeException('An integration with that name already exists');
201
        }
202
203
        $integrationModel = $this->integrationService->create([
204
            'name' => $integrationName,
205
            'email' => $integrationEmail,
206
            'status' => IntegrationAlias::STATUS_ACTIVE,
207
            'endpoint' => $integrationEndpoint,
208
            'setup_type' => IntegrationAlias::TYPE_MANUAL
209
        ]);
210
        return $integrationModel;
211
    }
212
213
    /**
214
     * @param IntegrationAlias $integrationModel
215
     * @param array $grantedResources
216
     * @throws LocalizedException
217
     */
218
    private function grantPermissions(IntegrationAlias $integrationModel, array $grantedResources)
219
    {
220
        if (empty($grantedResources)) {
221
            $this->authorizationService->grantAllPermissions($integrationModel->getId());
222
        } else {
223
            $this->authorizationService->grantPermissions($integrationModel->getId(), $grantedResources);
224
        }
225
    }
226
}
227