Skip to content
Snippets Groups Projects
Commit 52c6b351 authored by Xavier Jouslin de Noray's avatar Xavier Jouslin de Noray
Browse files

Upload Plugin: check if the plugin can be uploadable

Gitlab: #10
Change-Id: I9b5d44179c32a0d2bf4c1ddeaf2fb9e0fde059da
parent f7dac680
No related branches found
No related tags found
No related merge requests found
...@@ -247,6 +247,67 @@ export class PluginsController { ...@@ -247,6 +247,67 @@ export class PluginsController {
} }
} }
); );
/**
* @swagger
*
* /upload/{arch}/{id}:
* get:
* summary: Verify if the plugin is already uploaded with the same issuer
* description: Verify if the plugin is already uploaded with the same issuer
* tags: [Example, Time]
* parameters:
* - name: id
* in: path
* description: The ID of the plugin to be downloaded.
* required: true
* schema:
* type: string
* - name: arch
* in: path
* description: The architecture for which the plugin is requested.
* required: true
* schema:
* type: string
* responses:
* '200':
* description: The plugin is uploadable.
* '400':
* description: Bad request - When the 'id', 'arch' parameter or the 'Authorization' http header is missing.
* '403':
* description: Forbidden - When the plugin is already uploaded with a different issuer.
* '500':
* description: Internal server error - Something went wrong on the server.
*
*/
// GET /upload/:arch/:id
this.router.get('/upload/:arch/:id', (req: Request, res: Response) => {
try {
const clientCertificate = req.get('Authorization');
if (
req.params.id === undefined ||
req.params.arch === undefined ||
clientCertificate === undefined
) {
res.status(StatusCodes.BAD_REQUEST).send();
return;
}
this.pluginsManager
.isPluginUploadable(
req.params.id,
req.params.arch,
Buffer.from(clientCertificate, 'base64')
)
.then(isUploadable =>
res
.status(isUploadable ? StatusCodes.OK : StatusCodes.FORBIDDEN)
.send()
)
.catch(() => res.status(StatusCodes.INTERNAL_SERVER_ERROR).send());
} catch (e) {
res.status(StatusCodes.INTERNAL_SERVER_ERROR).send();
}
});
/** /**
* @swagger * @swagger
......
...@@ -66,10 +66,7 @@ export class CertificateManager { ...@@ -66,10 +66,7 @@ export class CertificateManager {
return Buffer.compare(signature, checkSignature) === 0; return Buffer.compare(signature, checkSignature) === 0;
} }
private async readCertificate( async readCertificate(path: string, file: string): Promise<X509Certificate> {
path: string,
file: string
): Promise<X509Certificate> {
return await this.fileManager return await this.fileManager
.readArchive(path, file) .readArchive(path, file)
.then((content: Buffer) => { .then((content: Buffer) => {
...@@ -90,4 +87,16 @@ export class CertificateManager { ...@@ -90,4 +87,16 @@ export class CertificateManager {
return acc; return acc;
}, {}); }, {});
} }
isSameKey(issuer: X509Certificate, plugin: X509Certificate): boolean {
const key1Formatted = issuer.publicKey.export({
format: 'pem',
type: 'pkcs1',
});
const key2Formatted = plugin.publicKey.export({
format: 'pem',
type: 'pkcs1',
});
return key1Formatted === key2Formatted;
}
} }
...@@ -23,6 +23,7 @@ import {TranslationService} from './translation.service'; ...@@ -23,6 +23,7 @@ import {TranslationService} from './translation.service';
import {CertificateManager} from './certificate.manager.service'; import {CertificateManager} from './certificate.manager.service';
import {ArchitectureManager} from './architecture.manager'; import {ArchitectureManager} from './architecture.manager';
import {basename, extname} from 'path'; import {basename, extname} from 'path';
import {X509Certificate} from 'crypto';
@Service() @Service()
export class PluginsManager { export class PluginsManager {
...@@ -253,6 +254,27 @@ export class PluginsManager { ...@@ -253,6 +254,27 @@ export class PluginsManager {
}; };
} }
async isPluginUploadable(
id: string,
arch: string,
requestCertificate: Buffer
): Promise<boolean> {
const requestedCertificate = new X509Certificate(requestCertificate);
const remotePlugin = await this.findPlugin(id, arch);
const remotePluginPath = await this.getPluginPath(id, arch);
if (remotePlugin === undefined || remotePluginPath === undefined) {
return true;
}
const remoteCertificate = await this.certificateManager.readCertificate(
remotePluginPath,
id + '.crt'
);
return this.certificateManager.isSameKey(
requestedCertificate,
remoteCertificate
);
}
async getVersions(): Promise<Array<{id: string; version: string}>> { async getVersions(): Promise<Array<{id: string; version: string}>> {
if (this.plugins.length === 0) { if (this.plugins.length === 0) {
await this.setPlugins(); await this.setPlugins();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment