From 3c3c014b476acd19ddee0ca337fa328d5b013e47 Mon Sep 17 00:00:00 2001 From: Sampsa Penna Date: Tue, 1 Mar 2022 15:38:56 +0200 Subject: [PATCH 001/559] support restricting project availability in backend --- swift_browser_ui/ui/api.py | 9 ++++- swift_browser_ui/ui/front.py | 12 +++++++ swift_browser_ui/ui/login.py | 57 ++++++++++++++++++++++++++++++ swift_browser_ui/ui/middlewares.py | 25 +++++++++++++ swift_browser_ui/ui/server.py | 12 ++++++- swift_browser_ui/ui/settings.py | 1 + tests/common/mockups.py | 2 ++ tests/ui_unit/test_api.py | 2 ++ tests/ui_unit/test_login.py | 1 + 9 files changed, 119 insertions(+), 2 deletions(-) diff --git a/swift_browser_ui/ui/api.py b/swift_browser_ui/ui/api.py index 333bb8185..a54026198 100644 --- a/swift_browser_ui/ui/api.py +++ b/swift_browser_ui/ui/api.py @@ -37,7 +37,14 @@ async def os_list_projects(request: aiohttp.web.Request) -> aiohttp.web.Response ) # Filter out the tokens contained in session token return aiohttp.web.json_response( - [{"name": v["name"], "id": v["id"]} for _, v in session["projects"].items()] + [ + { + "name": v["name"], + "id": v["id"], + "tainted": v["tainted"], + } + for _, v in session["projects"].items() + ] ) diff --git a/swift_browser_ui/ui/front.py b/swift_browser_ui/ui/front.py index 67342312a..ce7ee52f9 100644 --- a/swift_browser_ui/ui/front.py +++ b/swift_browser_ui/ui/front.py @@ -22,6 +22,18 @@ async def browse(_: aiohttp.web.Request) -> aiohttp.web.FileResponse: ) +async def select(_: aiohttp.web.Request) -> aiohttp.web.FileResponse: + """Serve a project selection for users with tainted projects.""" + return aiohttp.web.FileResponse( + str(setd["static_directory"]) + "/select.html", + headers={ + "Cache-Control": "no-cache, no-store, must-revalidate", + "Pragma": "no-cache", + "Expires": "0", + }, + ) + + async def index( request: typing.Optional[aiohttp.web.Request], ) -> typing.Union[aiohttp.web.Response, aiohttp.web.FileResponse]: diff --git a/swift_browser_ui/ui/login.py b/swift_browser_ui/ui/login.py index 2bea8d7d1..587266396 100644 --- a/swift_browser_ui/ui/login.py +++ b/swift_browser_ui/ui/login.py @@ -186,6 +186,8 @@ async def login_with_token( session["referer"] = request.url.host uname = "" + taint = True if setd["force_restricted_mode"] else False + # Check token availability avail = await get_availability_from_token(token, client) session["projects"] = {} @@ -242,12 +244,23 @@ async def login_with_token( "name": project["name"], "endpoint": endpoint["url"], "token": scoped, + "tainted": True if setd["force_restricted_mode"] else False, } session["token"] = token session["uname"] = uname + if taint: + session["taint"] = True + else: + session["taint"] = False + session.changed() + + if taint: + response.headers["Location"] = "/select" + return response + # Redirect to the browse page if "NAV_TO" in request.cookies.keys(): response.headers["Location"] = request.cookies["NAV_TO"] @@ -258,6 +271,50 @@ async def login_with_token( return response +async def handle_project_lock(request: aiohttp.web.Request) -> aiohttp.web.Response: + """Lock down to a specific project.""" + log = request.app["Log"] + log.info("Call for locking down the project.") + + session = await aiohttp_session.get_session(request) + + project = request.match_info["project"] + + # Ditch all projects that aren't the one specified if project is defined + if project in session["projects"]: + session["projects"] = { + k: v + for k, v in filter( + lambda val: val[0] == project, + session["projects"].items(), + ) + } + # If the project doesn't exist, allow all untainted projects + else: + session["projects"] = { + k: v + for k, v in filter( + lambda val: not val[1]["tainted"], session["projects"].items() + ) + } + + if not session["projects"]: + session.invalidate() + raise aiohttp.web.HTTPForbidden(reason="No untainted projects available.") + + # The session is no longer tainted if it's been locked + session["taint"] = False + + session.changed() + return aiohttp.web.Response( + status=303, + body=None, + headers={ + "Location": "/browse", + }, + ) + + async def handle_logout(request: aiohttp.web.Request) -> aiohttp.web.Response: """Properly kill the session for the user.""" log = request.app["Log"] diff --git a/swift_browser_ui/ui/middlewares.py b/swift_browser_ui/ui/middlewares.py index dbb2ba56a..8b17ac90d 100644 --- a/swift_browser_ui/ui/middlewares.py +++ b/swift_browser_ui/ui/middlewares.py @@ -9,6 +9,7 @@ from swift_browser_ui.ui.settings import setd + AiohttpHandler = typing.Callable[ [web.Request], typing.Coroutine[typing.Awaitable, typing.Any, web.Response] ] @@ -46,6 +47,30 @@ async def check_session_at( return await handler(request) +@web.middleware +async def check_session_taintness( + request: web.Request, + handler: AiohttpHandler, +) -> web.StreamResponse: + """Override tainted sessions with project selection until scoped.""" + session = await aiohttp_session.get_session(request) + if ( + "taint" in session + and session["taint"] + and "select" not in request.path + and "projects" not in request.path + and "lock" not in request.path + and "static" not in request.path + ): + return web.Response( + status=303, + headers={ + "Location": "/select", + }, + ) + return await handler(request) + + @web.middleware async def error_middleware(request: web.Request, handler: AiohttpHandler) -> web.Response: """Return the correct HTTP Error page.""" diff --git a/swift_browser_ui/ui/server.py b/swift_browser_ui/ui/server.py index 6b549fa74..5e69e311a 100644 --- a/swift_browser_ui/ui/server.py +++ b/swift_browser_ui/ui/server.py @@ -20,13 +20,14 @@ import aioredis -from swift_browser_ui.ui.front import index, browse, loginpassword +from swift_browser_ui.ui.front import index, browse, loginpassword, select from swift_browser_ui.ui.login import ( handle_login, handle_logout, sso_query_begin, sso_query_end, credentials_login_end, + handle_project_lock, ) from swift_browser_ui.ui.api import ( swift_get_metadata_container, @@ -82,6 +83,7 @@ async def servinit( middlewares = [ swift_browser_ui.ui.middlewares.error_middleware, swift_browser_ui.ui.middlewares.check_session_at, + swift_browser_ui.ui.middlewares.check_session_taintness, ] if inject_middleware: middlewares = middlewares + inject_middleware @@ -136,6 +138,14 @@ async def servinit( # Route all URLs prefixed by /browse to the browser page, as this is # an spa aiohttp.web.get("/browse/{tail:.*}", browse), + aiohttp.web.get("/select", select), + ] + ) + + # Add lock routes + app.add_routes( + [ + aiohttp.web.get("/lock/{project}", handle_project_lock), ] ) diff --git a/swift_browser_ui/ui/settings.py b/swift_browser_ui/ui/settings.py index 4596d2341..57bbdc0e5 100644 --- a/swift_browser_ui/ui/settings.py +++ b/swift_browser_ui/ui/settings.py @@ -70,6 +70,7 @@ "has_trust": environ.get("BROWSER_START_HAS_TRUST", False), "set_origin_address": environ.get("BROWSER_START_SET_ORIGIN_ADDRESS", None), "os_user_domain": environ.get("OS_USER_DOMAIN_NAME", "Default"), + "force_restricted_mode": environ.get("SWIFT_UI_FORCE_RESTRICTED_MODE", False), "logfile": None, "port": 8080, "verbose": False, diff --git a/tests/common/mockups.py b/tests/common/mockups.py index f2f76f7b6..e3177d457 100644 --- a/tests/common/mockups.py +++ b/tests/common/mockups.py @@ -32,12 +32,14 @@ def setUp(self): "name": "test-name-0", "token": "test-token-0", "endpoint": "https://test-endpoint-0/v1/AUTH_test-id-0", + "tainted": False, }, "test-id-1": { "id": "test-id-1", "name": "test-name-1", "token": "test-token-1", "endpoint": "https://test-endpoint-1/v1/AUTH_test-id-1", + "tainted": False, }, } self.aiohttp_session_get_session_mock = unittest.mock.AsyncMock() diff --git a/tests/ui_unit/test_api.py b/tests/ui_unit/test_api.py index 1b01ad520..8423e3bb5 100644 --- a/tests/ui_unit/test_api.py +++ b/tests/ui_unit/test_api.py @@ -35,10 +35,12 @@ async def test_os_list_projects(self): { "id": "test-id-0", "name": "test-name-0", + "tainted": False, }, { "id": "test-id-1", "name": "test-name-1", + "tainted": False, }, ] ) diff --git a/tests/ui_unit/test_login.py b/tests/ui_unit/test_login.py index 3ffda3b21..d1f8fa1d7 100644 --- a/tests/ui_unit/test_login.py +++ b/tests/ui_unit/test_login.py @@ -197,6 +197,7 @@ async def test_login_with_token(self): """ self.setd_mock["session_lifetime"] = 28800 self.setd_mock["history_lifetime"] = 2592000 + self.setd_mock["force_restricted_mode"] = False self.setd_mock["swift_endpoint_url"] = ("http://obj.exampleosep.com:443/v1",) patch1 = unittest.mock.patch( "swift_browser_ui.ui.login.setd", From 061d3d9ac9fd31de452c9e635550676885bf13dc Mon Sep 17 00:00:00 2001 From: Sampsa Penna Date: Tue, 1 Mar 2022 15:58:35 +0200 Subject: [PATCH 002/559] support restricting project availability in frontend --- .github/config/.finnishwords.txt | 32 ++++++++ swift_browser_ui_frontend/src/common/lang.js | 27 +++++++ .../src/entries/select.js | 51 +++++++++++++ .../src/pages/SelectPage.vue | 73 +++++++++++++++++++ swift_browser_ui_frontend/vue.config.js | 7 ++ 5 files changed, 190 insertions(+) create mode 100644 swift_browser_ui_frontend/src/entries/select.js create mode 100644 swift_browser_ui_frontend/src/pages/SelectPage.vue diff --git a/.github/config/.finnishwords.txt b/.github/config/.finnishwords.txt index 3629ed438..397cc63bc 100644 --- a/.github/config/.finnishwords.txt +++ b/.github/config/.finnishwords.txt @@ -1,5 +1,7 @@ + ajaksi alapuolisesta +alla aloitettiin annetut apin @@ -24,6 +26,7 @@ erillinen erissä esimerkiksi esitetty +estetty etsi etsittyä että @@ -32,6 +35,7 @@ etusivun hakea haku hakuindeksi +haluat haluatko halutako haluttu @@ -65,9 +69,11 @@ johtaa johtua jonka jos +jota julkinen julkiset julkisia +kaikki kansio kansioille kansioina @@ -86,6 +92,7 @@ käyttäjän käyttäjänimestä käyttöä käyttöliittymä +käyttöliittymän käyttörajoista kehittänyt kelpaa @@ -96,6 +103,8 @@ keskus kestää kiellettyä kirjaudu +kirjautuaksesi +kirjautumalla kirjautumisen kirjoitus kirjoitusoikeus @@ -162,6 +171,7 @@ mikä mikäli minuutin mitätöi +muiden muita mukaan muokataan @@ -172,7 +182,9 @@ muussa muutaman muuttaa muuttaaksesi +näkyvissä nämä +nappia navigointia näytä näytetään @@ -205,6 +217,7 @@ omistavan ongelmiin onnistui onnistunut +onnistuu operaatio operaation osoite @@ -237,13 +250,18 @@ polku postamista poudan projekteihin +projekteja projekti +projektia +projektien +projektien projektilla projektille projektilta projektin projektissa projektista +projektit projektitunnisteet projektitunnisteille pudota @@ -253,6 +271,13 @@ pyydetty pyydetyn pyyntö rajan +rajattu +rajatun +rajoitettua +rajoitettuihin +rajoittamattomat +rajoittamattomia +rajoittamattomien rajoitteiden resurssienkäyttö resurssit @@ -274,8 +299,12 @@ salausratkaisun salli sallittu selaamiseen +selailla +selailu selain selainta +selatessa +siirto sisään sisäänkirjauksen sisällön @@ -336,6 +365,7 @@ tilan tilankäyttö tilapäinen tilapäisesti +toiseen toteuttaa tueta tuettu @@ -358,8 +388,10 @@ uusi uusia vaatii vähintään +vaihto väliaikaiseen valikossa +valinnan valinnat valitse valittu diff --git a/swift_browser_ui_frontend/src/common/lang.js b/swift_browser_ui_frontend/src/common/lang.js index e908adc8a..bfc44ff80 100644 --- a/swift_browser_ui_frontend/src/common/lang.js +++ b/swift_browser_ui_frontend/src/common/lang.js @@ -300,6 +300,20 @@ let default_translations = { buildingIndex: "This project has a large number of objects. Please, " + "wait while the search index is ready, and try again.", }, + select: { + heading: "Select project for logging in", + description: "The user account used for logging in contains " + + "projects flagged as restricted. The interface scope is limited " + + "when a restricted project is opened, i.e. only the restricted " + + "project is visible during a restricted session. This means you " + + "cannot copy or move items across projects or view items in " + + "other projects available to you. Select a project you want to " + + "use from the following listing, after selection you will not be " + + "able to change the project without logging out. If you want to " + + "browse unrestricted projects, use the unrestricted projects " + + "button below.", + unrestricted: "All unrestricted projects", + }, }, }, fi: { @@ -594,6 +608,19 @@ let default_translations = { buildingIndex: "Tässä projektissa on suuri määrä kohteita. Odota, " + "kunnes hakuindeksi on valmis, ja yritä uudelleen.", }, + select: { + heading: "Valitse projekti kirjautuaksesi sisään", + description: "Käyttäjällä on pääsy rajoitettuihin projekteihin. " + + "Selatessa rajoitettua projektia käyttöliittymän pääsy on " + + "rajattu, eli vain rajatun projektin sisältö on näkyvissä. " + + "Tiedostojen kopiointi ja siirto projektista toiseen, ja " + + "muiden projektien sisällön selailu on estetty. Valitse " + + "projekti, jota haluat käyttää. Valinnan jälkeen projektin " + + "vaihto onnistuu vain kirjautumalla ulos. Mikäli haluat " + + "selailla vain rajoittamattomia projekteja, paina " + + "rajoittamattomien projektien nappia alla.", + unrestricted: "Kaikki rajoittamattomat projektit", + }, }, }, }; diff --git a/swift_browser_ui_frontend/src/entries/select.js b/swift_browser_ui_frontend/src/entries/select.js new file mode 100644 index 000000000..4c1d7e6cf --- /dev/null +++ b/swift_browser_ui_frontend/src/entries/select.js @@ -0,0 +1,51 @@ +import Vue from "vue"; +import App from "@/pages/SelectPage.vue"; +import Buefy from "buefy"; + +import getLangCookie from "@/common/conv"; +import translations from "@/common/lang"; + +import { getProjects } from "@/common/api"; + +// Import project css +import "@/css/prod.scss"; + +import VueI18n from "vue-i18n"; + +Vue.use(VueI18n); +Vue.use(Buefy); + + +const i18n = new VueI18n({ + locale: getLangCookie(), + messages: translations, +}); + +new Vue ({ + i18n, + data: { + formname: "Token id:", + loginformname: "Openstack account:", + idb: true, + projects: [], + langs: [{ph: "In English", value: "en"}, {ph: "Suomeksi", value: "fi"}], + }, + created() { + document.title = this.$t("message.program_name"); + this.updateProjects(); + }, + methods: { + "updateProjects": function () { + getProjects().then(ret => this.projects = ret); + }, + setCookieLang: function() { + const expiryDate = new Date(); + expiryDate.setMonth(expiryDate.getMonth() + 1); + document.cookie = "OBJ_UI_LANG=" + + i18n.locale + + "; path=/; expires=" + + expiryDate.toUTCString(); + }, + }, + ...App, +}).$mount("#app"); diff --git a/swift_browser_ui_frontend/src/pages/SelectPage.vue b/swift_browser_ui_frontend/src/pages/SelectPage.vue new file mode 100644 index 000000000..939bbbcfb --- /dev/null +++ b/swift_browser_ui_frontend/src/pages/SelectPage.vue @@ -0,0 +1,73 @@ + + + diff --git a/swift_browser_ui_frontend/vue.config.js b/swift_browser_ui_frontend/vue.config.js index 0ba8009b5..0eaeed648 100644 --- a/swift_browser_ui_frontend/vue.config.js +++ b/swift_browser_ui_frontend/vue.config.js @@ -17,6 +17,13 @@ module.exports = { // eslint-disable-line title: "Swift browser UI", chunks: ["chunk-vendors", "chunk-common", "index"], }, + select: { + entry: "src/entries/select.js", + template: "public/select.html", + filename: "select.html", + title: "Select a project to isolate", + chunks: ["chunk-vendors", "chunk-common", "select"], + }, badrequest: { entry: "src/entries/badrequest.js", template: "public/index.html", From e5d2c576ee0f22bd1a91e835eadc3fb665dbc8ea Mon Sep 17 00:00:00 2001 From: Sampsa Penna Date: Thu, 3 Mar 2022 09:10:20 +0200 Subject: [PATCH 003/559] increment changelog for restricted project support --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a588edbc..94ec91a1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- (GH #468) add support for project isolation for projects marked as restricted + - discovery for restricted projects pending, implemented logic only for now + - foced restricted mode can be configured on + + ## [v2.0.0] ### Added From 06688ee4c86db58fc3bf3bb1e0d7c058b4ea5875 Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:06:49 +0200 Subject: [PATCH 004/559] Fix container metadata updates. --- swift_browser_ui/ui/api.py | 2 +- tests/ui_unit/test_api.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/swift_browser_ui/ui/api.py b/swift_browser_ui/ui/api.py index a54026198..0510a6aa2 100644 --- a/swift_browser_ui/ui/api.py +++ b/swift_browser_ui/ui/api.py @@ -383,7 +383,7 @@ async def swift_update_container_metadata( project = request.match_info["project"] container = request.match_info["container"] meta = await request.json() - meta = {f"X-Container-Meta-{k}": v for k, v in meta} + meta = {f"X-Container-Meta-{k}": v for k, v in meta.items()} headers = { "X-Auth-Token": session["projects"][project]["token"], } diff --git a/tests/ui_unit/test_api.py b/tests/ui_unit/test_api.py index 8423e3bb5..f1bf901d7 100644 --- a/tests/ui_unit/test_api.py +++ b/tests/ui_unit/test_api.py @@ -346,10 +346,10 @@ async def test_batch_swift_update_object_metadata_no_objects(self): async def test_swift_update_container_metadata(self): """Test container metadata update with Openstack.""" self.mock_request.json = unittest.mock.AsyncMock( - return_value=[ - ("meta0", "test-data"), - ("meta1", "more-test-data"), - ], + return_value={ + "meta0": "test-data", + "meta1": "more-test-data", + }, ) with self.p_get_sess: resp = await swift_browser_ui.ui.api.swift_update_container_metadata( From 5950d7c20cb26ce7401d2c879b666a18fa8ba82a Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:07:32 +0200 Subject: [PATCH 005/559] Fix object metadata update. --- swift_browser_ui/ui/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift_browser_ui/ui/api.py b/swift_browser_ui/ui/api.py index 0510a6aa2..a1b792001 100644 --- a/swift_browser_ui/ui/api.py +++ b/swift_browser_ui/ui/api.py @@ -363,7 +363,7 @@ async def swift_batch_update_object_metadata( ] batch = await asyncio.gather(*batch, return_exceptions=False) for ret in batch: - if ret != 204: + if ret not in {202, 204}: raise aiohttp.web.HTTPNotFound return aiohttp.web.HTTPNoContent() From f8d73d7a5a9b842133c697fa6fe8379e2ceb7842 Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:07:56 +0200 Subject: [PATCH 006/559] Make user roles configurable. --- swift_browser_ui/ui/login.py | 2 +- swift_browser_ui/ui/settings.py | 1 + tests/ui_unit/test_login.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/swift_browser_ui/ui/login.py b/swift_browser_ui/ui/login.py index 587266396..c3f92c12c 100644 --- a/swift_browser_ui/ui/login.py +++ b/swift_browser_ui/ui/login.py @@ -220,7 +220,7 @@ async def login_with_token( obj_role = False request.app["Log"].debug(f'roles: {ret["token"]["roles"]}') for role in ret["token"]["roles"]: - if role["name"] == "object_store_user": + if role["name"] in str(setd["os_accepted_roles"]).split(";"): obj_role = True if not obj_role: continue diff --git a/swift_browser_ui/ui/settings.py b/swift_browser_ui/ui/settings.py index 57bbdc0e5..07e509866 100644 --- a/swift_browser_ui/ui/settings.py +++ b/swift_browser_ui/ui/settings.py @@ -70,6 +70,7 @@ "has_trust": environ.get("BROWSER_START_HAS_TRUST", False), "set_origin_address": environ.get("BROWSER_START_SET_ORIGIN_ADDRESS", None), "os_user_domain": environ.get("OS_USER_DOMAIN_NAME", "Default"), + "os_accepted_roles": environ.get("OS_ACCEPTED_ROLES", "object_store_user"), "force_restricted_mode": environ.get("SWIFT_UI_FORCE_RESTRICTED_MODE", False), "logfile": None, "port": 8080, diff --git a/tests/ui_unit/test_login.py b/tests/ui_unit/test_login.py index d1f8fa1d7..b4af2c0ec 100644 --- a/tests/ui_unit/test_login.py +++ b/tests/ui_unit/test_login.py @@ -199,6 +199,7 @@ async def test_login_with_token(self): self.setd_mock["history_lifetime"] = 2592000 self.setd_mock["force_restricted_mode"] = False self.setd_mock["swift_endpoint_url"] = ("http://obj.exampleosep.com:443/v1",) + self.setd_mock["os_accepted_roles"] = "object_store_user" patch1 = unittest.mock.patch( "swift_browser_ui.ui.login.setd", self.setd_mock, From 4e8fa3cb5c3f34efc50d59ee44f3433fe2b588f8 Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:08:34 +0200 Subject: [PATCH 007/559] EditObject gets project from URL params. --- swift_browser_ui_frontend/src/views/EditObject.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift_browser_ui_frontend/src/views/EditObject.vue b/swift_browser_ui_frontend/src/views/EditObject.vue index ddd37156f..1465ce200 100644 --- a/swift_browser_ui_frontend/src/views/EditObject.vue +++ b/swift_browser_ui_frontend/src/views/EditObject.vue @@ -81,7 +81,7 @@ export default { }); } else { this.container = await this.$store.state.db.containers.get({ - projectID: this.$store.state.active.id, + projectID: this.$route.params.project, name: this.$route.params.container, }); this.object = await this.$store.state.db.objects.get({ From 872c32564b27e0245b9b49ae8ce331e8bc2f1f56 Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:09:01 +0200 Subject: [PATCH 008/559] Make dashboard function as expected. --- swift_browser_ui_frontend/src/common/router.js | 2 +- swift_browser_ui_frontend/src/views/Dashboard.vue | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/swift_browser_ui_frontend/src/common/router.js b/swift_browser_ui_frontend/src/common/router.js index ce751f92c..66623ddc5 100644 --- a/swift_browser_ui_frontend/src/common/router.js +++ b/swift_browser_ui_frontend/src/common/router.js @@ -87,7 +87,7 @@ export default new Router({ component: ReplicationView, }, { - path: "/browse/:user", + path: "/browse/:user/:project/info", name: "DashboardView", component: DashboardView, }, diff --git a/swift_browser_ui_frontend/src/views/Dashboard.vue b/swift_browser_ui_frontend/src/views/Dashboard.vue index 2cb437834..ebae0fb74 100644 --- a/swift_browser_ui_frontend/src/views/Dashboard.vue +++ b/swift_browser_ui_frontend/src/views/Dashboard.vue @@ -161,6 +161,12 @@ export default { return this.$store.state.active; }, }, + watch: { + active () { + this.fetchMeta(); + this.disable(); + }, + }, beforeMount(){ // Fetch relevant things upon initializing the class instance this.fetchMeta(); From 34fbf24ec3d04553a07ba80a0e484bffe0e98ebe Mon Sep 17 00:00:00 2001 From: Felipe Morato Date: Fri, 11 Mar 2022 10:09:53 +0200 Subject: [PATCH 009/559] Run integration tests against keystone-swift docker container. --- .github/workflows/e2etests.yml | 36 +++++++++++- .../src/components/BrowserNavbar.vue | 1 + .../src/views/EditObject.vue | 1 + tests/cypress/integration/browser.spec.js | 56 ++++++++----------- tests/cypress/integration/userInfo.spec.js | 38 +++++-------- tests/cypress/support/commands.js | 8 +-- 6 files changed, 75 insertions(+), 65 deletions(-) diff --git a/.github/workflows/e2etests.yml b/.github/workflows/e2etests.yml index 0bbf9621f..a9005c995 100644 --- a/.github/workflows/e2etests.yml +++ b/.github/workflows/e2etests.yml @@ -1,5 +1,5 @@ name: End-to-end tests -on: [pull_request] +on: [push, pull_request] jobs: cypress-e2e-headless: @@ -9,8 +9,37 @@ jobs: matrix: node: ["16"] browser: ["firefox", "chrome"] + + # https://docs.github.com/en/actions/using-containerized-services/about-service-containers + services: + redis: + image: redis:alpine + ports: + - 6379:6379 + postgres: + image: postgres:alpine + env: + POSTGRES_PASSWORD: pass + ports: + - 5432:5432 + volumes: + - ${{ github.workspace }}/.github/config/init-project-db.sh:/docker-entrypoint-initdb.d/init-user-db.sh + keystone-swift: + image: ghcr.io/cscfi/docker-keystone-swift:main + ports: + - 5000:5000 + - 8080:8080 + options: >- + --name keystone-swift + --init steps: + - name: fix-permissions + run: sudo chown -R $USER:$USER ${{ github.workspace }} - uses: actions/checkout@v3 + - name: Populate swift + run: | + docker exec keystone-swift generate_data.py --keystone --username swift --password veryfast --containers 15 + docker exec keystone-swift generate_data.py --keystone --username swift --password veryfast --project "swift-project" - name: Build Frontend run: | pushd swift_browser_ui_frontend @@ -19,14 +48,15 @@ jobs: - name: Setup and Run backend run: | pip install -r requirements.txt - python -m tests.ui_unit.mock_server & + pip install honcho + honcho start -f ${{ github.workspace }}/.github/config/Procfile --env ${{ github.workspace }}/.github/config/.env.test & - run: npm i cypress - uses: cypress-io/github-action@v2 with: install: false browser: ${{ matrix.browser }} headless: true - env: port=8080 + env: port=8000 - uses: actions/upload-artifact@v2 if: failure() with: diff --git a/swift_browser_ui_frontend/src/components/BrowserNavbar.vue b/swift_browser_ui_frontend/src/components/BrowserNavbar.vue index bcf9d5776..4c635f858 100644 --- a/swift_browser_ui_frontend/src/components/BrowserNavbar.vue +++ b/swift_browser_ui_frontend/src/components/BrowserNavbar.vue @@ -127,6 +127,7 @@