Passed
Push — 1.11.x ( 1a2284...d20441 )
by Angel Fernando Quiroz
11:23
created

LtiProviderPlugin::isInstructor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/* For license terms, see /license.txt */
3
4
use Chamilo\PluginBundle\Entity\LtiProvider\Platform;
5
use Chamilo\PluginBundle\Entity\LtiProvider\PlatformKey;
6
use Doctrine\ORM\OptimisticLockException;
7
use Doctrine\ORM\Tools\SchemaTool;
8
9
/**
10
 * Description of LtiProvider.
11
 *
12
 * @author Christian Beeznest <[email protected]>
13
 */
14
class LtiProviderPlugin extends Plugin
15
{
16
    const TABLE_PLATFORM = 'plugin_lti_provider_platform';
17
18
    public $isAdminPlugin = true;
19
20
    protected function __construct()
21
    {
22
        $version = '1.0';
23
        $author = 'Christian Beeznest';
24
25
        $message = Display::return_message($this->get_lang('Description'));
26
27
        if ($this->areTablesCreated()) {
28
            $publicKey = $this->getPublicKey();
29
30
            $pkHtml = '<div class="form-group">
31
                    <label for="lti_provider_public_key" class="col-sm-2 control-label">'
32
                .$this->get_lang('PublicKey').'</label>
33
                    <div class="col-sm-8">
34
                        <pre>'.$publicKey.'</pre>
35
                    </div>
36
                    <div class="col-sm-2"></div>
37
                </div>';
38
        } else {
39
            $pkHtml = $this->get_lang('GenerateKeyPairInfo');
40
        }
41
42
        $settings = [
43
            $message => 'html',
44
            'name' => 'text',
45
            'launch_url' => 'text',
46
            'login_url' => 'text',
47
            'redirect_url' => 'text',
48
            $pkHtml => 'html',
49
            'enabled' => 'boolean',
50
        ];
51
        parent::__construct($version, $author, $settings);
52
    }
53
54
    /**
55
     * Get a selectbox with quizzes in courses , used for a tool provider.
56
     *
57
     * @param null $issuer
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $issuer is correct as it would always require null to be passed?
Loading history...
58
     *
59
     * @return string
60
     */
61
    public function getQuizzesSelect($issuer = null)
62
    {
63
        $courses = CourseManager::get_courses_list();
64
        $toolProvider = $this->getToolProvider($issuer);
65
        $htmlcontent = '<div class="form-group">
66
            <label for="lti_provider_create_platform_kid" class="col-sm-2 control-label">'.$this->get_lang('ToolProvider').'</label>
67
            <div class="col-sm-8">
68
                <select name="tool_provider">';
69
        $htmlcontent .= '<option value="">-- '.$this->get_lang('SelectOneActivity').' --</option>';
70
        foreach ($courses as $course) {
71
            $courseInfo = api_get_course_info($course['code']);
72
            $optgroupLabel = "{$course['title']} : ".get_lang('Quizzes');
73
            $htmlcontent .= '<optgroup label="'.$optgroupLabel.'">';
74
            $exerciseList = ExerciseLib::get_all_exercises_for_course_id(
75
                $courseInfo,
76
                0,
77
                $course['id'],
78
                false
79
            );
80
            foreach ($exerciseList as $key => $exercise) {
81
                $selectValue = "{$course['code']}@@quiz-{$exercise['iid']}";
82
                $htmlcontent .= '<option value="'.$selectValue.'" '.($toolProvider == $selectValue ? ' selected="selected"' : '').'>'.Security::remove_XSS($exercise['title']).'</option>';
83
            }
84
            $htmlcontent .= '</optgroup>';
85
        }
86
        $htmlcontent .= "</select>";
87
        $htmlcontent .= '   </div>
88
                    <div class="col-sm-2"></div>
89
                    </div>';
90
91
        return $htmlcontent;
92
    }
93
94
    /**
95
     * Get the public key.
96
     */
97
    public function getPublicKey(): string
98
    {
99
        $publicKey = '';
100
        $platformKey = Database::getManager()
101
           ->getRepository('ChamiloPluginBundle:LtiProvider\PlatformKey')
102
           ->findOneBy([]);
103
104
        if ($platformKey) {
105
            $publicKey = $platformKey->getPublicKey();
106
        }
107
108
        return $publicKey;
109
    }
110
111
    /**
112
     * Get the tool provider.
113
     */
114
    public function getToolProvider($issuer): string
115
    {
116
        $toolProvider = '';
117
        $platform = Database::getManager()
118
            ->getRepository('ChamiloPluginBundle:LtiProvider\Platform')
119
            ->findOneBy(['issuer' => $issuer]);
120
121
        if ($platform) {
122
            $toolProvider = $platform->getToolProvider();
123
        }
124
125
        return $toolProvider;
126
    }
127
128
    public function getToolProviderVars($issuer): array
129
    {
130
        $toolProvider = $this->getToolProvider($issuer);
131
        list($courseCode, $tool) = explode('@@', $toolProvider);
132
        list($toolName, $toolId) = explode('-', $tool);
133
        $vars = ['courseCode' => $courseCode, 'toolName' => $toolName, 'toolId' => $toolId];
134
135
        return $vars;
136
    }
137
138
    /**
139
     * Get the class instance.
140
     *
141
     * @staticvar LtiProviderPlugin $result
142
     */
143
    public static function create(): LtiProviderPlugin
144
    {
145
        static $result = null;
146
147
        return $result ?: $result = new self();
148
    }
149
150
    /**
151
     * Check whether the current user is a teacher in this context.
152
     */
153
    public static function isInstructor()
154
    {
155
        api_is_allowed_to_edit(false, true);
156
    }
157
158
    /**
159
     * Get the plugin directory name.
160
     */
161
    public function get_name(): string
162
    {
163
        return 'lti_provider';
164
    }
165
166
    /**
167
     * Install the plugin. Set the database up.
168
     *
169
     * @throws \Doctrine\ORM\Tools\ToolsException
170
     */
171
    public function install()
172
    {
173
        $em = Database::getManager();
174
175
        if ($em->getConnection()->getSchemaManager()->tablesExist(['sfu_post'])) {
176
            return;
177
        };
178
179
        $schemaTool = new SchemaTool($em);
180
        $schemaTool->createSchema(
181
            [
182
                $em->getClassMetadata(Platform::class),
183
                $em->getClassMetadata(PlatformKey::class),
184
            ]
185
        );
186
    }
187
188
    /**
189
     * Save configuration for plugin.
190
     *
191
     * Generate a new key pair for platform when enabling plugin.
192
     *
193
     * @throws OptimisticLockException
194
     * @throws \Doctrine\ORM\ORMException
195
     *
196
     * @return $this|Plugin
197
     */
198
    public function performActionsAfterConfigure()
199
    {
200
        $em = Database::getManager();
201
202
        /** @var PlatformKey $platformKey */
203
        $platformKey = $em
204
            ->getRepository('ChamiloPluginBundle:LtiProvider\PlatformKey')
205
            ->findOneBy([]);
206
207
        if ($this->get('enabled') === 'true') {
208
            if (!$platformKey) {
0 ignored issues
show
introduced by
$platformKey is of type Chamilo\PluginBundle\Ent...LtiProvider\PlatformKey, thus it always evaluated to true.
Loading history...
209
                $platformKey = new PlatformKey();
210
            }
211
212
            $keyPair = self::generatePlatformKeys();
213
214
            $platformKey->setKid($keyPair['kid']);
215
            $platformKey->publicKey = $keyPair['public'];
216
            $platformKey->setPrivateKey($keyPair['private']);
217
218
            $em->persist($platformKey);
219
        } else {
220
            if ($platformKey) {
0 ignored issues
show
introduced by
$platformKey is of type Chamilo\PluginBundle\Ent...LtiProvider\PlatformKey, thus it always evaluated to true.
Loading history...
221
                $em->remove($platformKey);
222
            }
223
        }
224
225
        $em->flush();
226
227
        return $this;
228
    }
229
230
    /**
231
     * Unistall plugin. Clear the database.
232
     */
233
    public function uninstall()
234
    {
235
        $em = Database::getManager();
236
237
        if (!$em->getConnection()->getSchemaManager()->tablesExist(['sfu_post'])) {
238
            return;
239
        };
240
241
        $schemaTool = new SchemaTool($em);
242
        $schemaTool->dropSchema(
243
            [
244
                $em->getClassMetadata(Platform::class),
245
                $em->getClassMetadata(PlatformKey::class),
246
            ]
247
        );
248
    }
249
250
    public function trimParams(array &$params)
251
    {
252
        foreach ($params as $key => $value) {
253
            $newValue = preg_replace('/\s+/', ' ', $value);
254
            $params[$key] = trim($newValue);
255
        }
256
    }
257
258
    private function areTablesCreated(): bool
259
    {
260
        $entityManager = Database::getManager();
261
        $connection = $entityManager->getConnection();
262
263
        return $connection->getSchemaManager()->tablesExist(self::TABLE_PLATFORM);
264
    }
265
266
    /**
267
     * Generate a key pair and key id for the platform.
268
     *
269
     * Return a associative array like ['kid' => '...', 'private' => '...', 'public' => '...'].
270
     */
271
    private static function generatePlatformKeys(): array
272
    {
273
        // Create the private and public key
274
        $res = openssl_pkey_new(
275
            [
276
                'digest_alg' => 'sha256',
277
                'private_key_bits' => 2048,
278
                'private_key_type' => OPENSSL_KEYTYPE_RSA,
279
            ]
280
        );
281
282
        // Extract the private key from $res to $privateKey
283
        $privateKey = '';
284
        openssl_pkey_export($res, $privateKey);
285
286
        // Extract the public key from $res to $publicKey
287
        $publicKey = openssl_pkey_get_details($res);
288
289
        return [
290
            'kid' => bin2hex(openssl_random_pseudo_bytes(10)),
291
            'private' => $privateKey,
292
            'public' => $publicKey["key"],
293
        ];
294
    }
295
296
    /**
297
     * Get a SimpleXMLElement object with the request received on php://input.
298
     *
299
     * @throws Exception
300
     */
301
    private function getRequestXmlElement(): ?SimpleXMLElement
0 ignored issues
show
Unused Code introduced by
The method getRequestXmlElement() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
302
    {
303
        $request = file_get_contents("php://input");
304
305
        if (empty($request)) {
306
            return null;
307
        }
308
309
        return new SimpleXMLElement($request);
310
    }
311
}
312