From b56fcc7def77f1e4a308e8b8ba3618cfdb2d3167 Mon Sep 17 00:00:00 2001 From: bilaldbank Date: Wed, 17 May 2023 15:54:30 +0500 Subject: [PATCH 1/5] add endpoint for removing package --- unpub/lib/src/app.dart | 35 ++++++++++++++++++++++++++++++++-- unpub/lib/src/app.g.dart | 5 +++++ unpub/lib/src/meta_store.dart | 2 ++ unpub/lib/src/mongo_store.dart | 5 +++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/unpub/lib/src/app.dart b/unpub/lib/src/app.dart index a64135f4..22758d6b 100644 --- a/unpub/lib/src/app.dart +++ b/unpub/lib/src/app.dart @@ -51,6 +51,9 @@ class App { final Future Function( Map pubspec, String uploaderEmail)? uploadValidator; + /// start time of the server + final DateTime startTime; + App({ required this.metaStore, required this.packageStore, @@ -59,7 +62,7 @@ class App { this.uploadValidator, this.proxy_origin, this.opaqueToken, - }); + }) : startTime = DateTime.now(); static shelf.Response _okWithJson(Map data) => shelf.Response.ok( @@ -379,6 +382,25 @@ class App { return _successMessage('uploader removed'); } + @Route.delete('/api/packages/') + Future removePackage(shelf.Request req, String name) async { + try { + await _validateOpaqueToken(req); + + final package = await metaStore.queryPackage(name); + + if (package == null) { + return _badRequest('package not found'); + } + + /// TODO: Throw exception if other packages depend on this + await metaStore.removePackage(name); + return _successMessage('package removed'); + } catch (err) { + return _badRequest(err.toString()); + } + } + @Route.get('/webapi/packages') Future getPackages(shelf.Request req) async { var params = req.requestedUri.queryParameters; @@ -510,10 +532,19 @@ class App { @Route.get('/packages/') @Route.get('/packages//versions/') Future indexHtml(shelf.Request req) async { - return shelf.Response.ok(index_html.content, + final updatedHtmlContent = _addStartTimeInHtml(); + + return shelf.Response.ok(updatedHtmlContent, headers: {HttpHeaders.contentTypeHeader: ContentType.html.mimeType}); } + /// Update the title in HTML to include server start time + String _addStartTimeInHtml() { + final updatedHtml = index_html.content + .replaceFirst('Unpub', '<title>Unpub $startTime'); + return updatedHtml; + } + @Route.get('/main.dart.js') Future<shelf.Response> mainDartJs(shelf.Request req) async { return shelf.Response.ok(main_dart_js.content, diff --git a/unpub/lib/src/app.g.dart b/unpub/lib/src/app.g.dart index 77fe24fb..885d709b 100644 --- a/unpub/lib/src/app.g.dart +++ b/unpub/lib/src/app.g.dart @@ -48,6 +48,11 @@ Router _$AppRouter(App service) { r'/api/packages/<name>/uploaders/<email>', service.removeUploader, ); + router.add( + 'DELETE', + r'/api/packages/<name>', + service.removePackage, + ); router.add( 'GET', r'/webapi/packages', diff --git a/unpub/lib/src/meta_store.dart b/unpub/lib/src/meta_store.dart index 7cf655cd..1280b744 100644 --- a/unpub/lib/src/meta_store.dart +++ b/unpub/lib/src/meta_store.dart @@ -19,4 +19,6 @@ abstract class MetaStore { String? uploader, String? dependency, }); + + Future<void> removePackage(String name); } diff --git a/unpub/lib/src/mongo_store.dart b/unpub/lib/src/mongo_store.dart index 13c17cd1..0f2937ce 100644 --- a/unpub/lib/src/mongo_store.dart +++ b/unpub/lib/src/mongo_store.dart @@ -101,4 +101,9 @@ class MongoStore extends MetaStore { return _queryPackagesBySelector(selector); } + + @override + removePackage(String name) async { + await db.collection(packageCollection).deleteOne(_selectByName(name)); + } } From 9152534a57167c0031118b36a585c96c40eca32f Mon Sep 17 00:00:00 2001 From: bilaldbank <bilal.akmal@din.global> Date: Wed, 17 May 2023 18:03:48 +0500 Subject: [PATCH 2/5] add test for removePackage endpoint --- unpub/test/unpub_test.dart | 27 +++++++++++++++++++++++++++ unpub/test/utils.dart | 5 +++++ 2 files changed, 32 insertions(+) diff --git a/unpub/test/unpub_test.dart b/unpub/test/unpub_test.dart index e7af2862..b7702429 100644 --- a/unpub/test/unpub_test.dart +++ b/unpub/test/unpub_test.dart @@ -267,6 +267,33 @@ main() { }); }); + group('remove package', () { + setUpAll(() async { + await _cleanUpDb(); + _server = await createServer(email0); + await pubPublish(package0, '0.0.1'); + }); + + tearDownAll(() async { + await _server.close(); + }); + + test('remove existing package', () async { + final initialRes = await getVersions(package0); + expect(initialRes.statusCode, HttpStatus.ok); + + await removePackage(package0); + + final response = await getVersions(package0); + expect(response.statusCode, HttpStatus.notFound); + }); + + test('remove non-existant package', () async { + final res = await removePackage(notExistingPacakge); + expect(res.statusCode, HttpStatus.badRequest); + }); + }); + group('uploader', () { setUpAll(() async { await _cleanUpDb(); diff --git a/unpub/test/utils.dart b/unpub/test/utils.dart index 3ecdfcfb..18707e68 100644 --- a/unpub/test/utils.dart +++ b/unpub/test/utils.dart @@ -48,6 +48,11 @@ Future<ProcessResult> pubPublish(String name, String version) { environment: {'PUB_HOSTED_URL': pubHostedUrl}); } +Future<http.Response> removePackage(String name){ + final encodedName = Uri.encodeComponent(name); + return http.delete(baseUri.resolve('/api/packages/$encodedName')); +} + Future<ProcessResult> pubUploader(String name, String operation, String email) { assert(['add', 'remove'].contains(operation), 'operation error'); From f884db5aef11e9b940b93a5a787421cf48a58a0d Mon Sep 17 00:00:00 2001 From: bilaldbank <bilal.akmal@din.global> Date: Thu, 18 May 2023 19:57:41 +0500 Subject: [PATCH 3/5] remove tar files from Filestore --- unpub/lib/src/app.dart | 9 ++++++++- unpub/lib/src/file_store.dart | 6 ++++++ unpub/lib/src/package_store.dart | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/unpub/lib/src/app.dart b/unpub/lib/src/app.dart index 22758d6b..e7c93b1e 100644 --- a/unpub/lib/src/app.dart +++ b/unpub/lib/src/app.dart @@ -394,7 +394,14 @@ class App { } /// TODO: Throw exception if other packages depend on this - await metaStore.removePackage(name); + + + /// Remove files + final versions = package.versions.map((v) => v.version).toList(); + await packageStore.remove(package.name, versions); + + /// Remove metadata (after removing the package tars) + await metaStore.removePackage(package.name); return _successMessage('package removed'); } catch (err) { return _badRequest(err.toString()); diff --git a/unpub/lib/src/file_store.dart b/unpub/lib/src/file_store.dart index a760b5a8..911e187b 100644 --- a/unpub/lib/src/file_store.dart +++ b/unpub/lib/src/file_store.dart @@ -25,4 +25,10 @@ class FileStore extends PackageStore { Stream<List<int>> download(String name, String version) { return _getTarballFile(name, version).openRead(); } + + @override + Future<void> remove(String name, List<String> versions) async { + final files = versions.map((v) => _getTarballFile(name, v)).toList(); + await Future.wait(files.map((e) => e.delete())); + } } diff --git a/unpub/lib/src/package_store.dart b/unpub/lib/src/package_store.dart index ed50aa14..656beb1b 100644 --- a/unpub/lib/src/package_store.dart +++ b/unpub/lib/src/package_store.dart @@ -12,4 +12,6 @@ abstract class PackageStore { } Future<void> upload(String name, String version, List<int> content); + + Future<void> remove(String name, List<String> versions); } From c449a0aa3c5f0b18e9a7bf54a488da8f3eacc790 Mon Sep 17 00:00:00 2001 From: bilaldbank <bilal.akmal@din.global> Date: Fri, 19 May 2023 12:22:38 +0500 Subject: [PATCH 4/5] add wip Dockerfile --- Dockerfile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..f36fa4b3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM google/dart:2.12 AS builder + +WORKDIR /app +COPY unpub_web/pubspec.* ./ +RUN dart pub get + +COPY . . + +WORKDIR /app/unpub_web + +RUN dart pub get --offline + +RUN dart pub global activate webdev 2.7.4 + +RUN dart pub global run webdev build + +# THIS IS A WIP, IT SHOULD BUILD THE WEB FOLDER +# SO WE CAN COPY IT TO THE UNPUB FOLDER \ No newline at end of file From ba2fcce079172f8b2e8861ca3442f0005ba1171b Mon Sep 17 00:00:00 2001 From: bilaldbank <bilal.akmal@din.global> Date: Fri, 19 May 2023 16:53:30 +0500 Subject: [PATCH 5/5] Revert "add wip Dockerfile" This reverts commit c449a0aa3c5f0b18e9a7bf54a488da8f3eacc790. --- Dockerfile | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f36fa4b3..00000000 --- a/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -FROM google/dart:2.12 AS builder - -WORKDIR /app -COPY unpub_web/pubspec.* ./ -RUN dart pub get - -COPY . . - -WORKDIR /app/unpub_web - -RUN dart pub get --offline - -RUN dart pub global activate webdev 2.7.4 - -RUN dart pub global run webdev build - -# THIS IS A WIP, IT SHOULD BUILD THE WEB FOLDER -# SO WE CAN COPY IT TO THE UNPUB FOLDER \ No newline at end of file