From 4b194376b31dc4eece1bf394092c5b6995b586eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Sun, 17 Sep 2023 12:39:39 +0200 Subject: [PATCH 1/2] [NO-ISSUE] Configure the API gateway --- deployment/flora.nginx | 40 +++++++++++++++++++++++ src/web/FloraWeb/Pages/Routes.hs | 1 + src/web/FloraWeb/Pages/Server.hs | 5 +++ src/web/FloraWeb/Pages/Server/Packages.hs | 29 ++++++---------- src/web/FloraWeb/Pages/Templates/Error.hs | 7 ++-- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/deployment/flora.nginx b/deployment/flora.nginx index 58837cd05..5d0cd360b 100644 --- a/deployment/flora.nginx +++ b/deployment/flora.nginx @@ -57,6 +57,45 @@ server { add_header X-Content-Type-Options nosniff; } + location /api { + return 301 /notfound; + } + + location / { + proxy_set_header Connection "upgrade"; + proxy_set_header Host $http_host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Request-ID $request_id; + proxy_redirect off; + proxy_pass http://localhost:8083; + } +} + +server { + listen api.xxxx:443 ssl http2; + server_name api.xxxx; + + ssl_certificate /etc/letsencrypt/live/api.xxxx/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/api.xxxx/privkey.pem; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; + ssl_ecdh_curve secp384r1; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + + add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + + access_log /var/log/nginx/flora_access.log; + error_log /var/log/nginx/flora_error.log; + location / { proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; @@ -65,6 +104,7 @@ server { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Request-ID $request_id; proxy_redirect off; + rewrite ^/api/?(.*) /$1 break; proxy_pass http://localhost:8083; } } diff --git a/src/web/FloraWeb/Pages/Routes.hs b/src/web/FloraWeb/Pages/Routes.hs index 13674d7a6..e4c162634 100644 --- a/src/web/FloraWeb/Pages/Routes.hs +++ b/src/web/FloraWeb/Pages/Routes.hs @@ -20,5 +20,6 @@ data Routes' mode = Routes' , packages :: mode :- "packages" :> Packages.Routes , categories :: mode :- "categories" :> Categories.Routes , search :: mode :- "search" :> Search.Routes + , notFound :: mode :- Get '[HTML] (Html ()) } deriving stock (Generic) diff --git a/src/web/FloraWeb/Pages/Server.hs b/src/web/FloraWeb/Pages/Server.hs index 6f98e24c7..7f33ad225 100644 --- a/src/web/FloraWeb/Pages/Server.hs +++ b/src/web/FloraWeb/Pages/Server.hs @@ -14,6 +14,7 @@ import FloraWeb.Pages.Server.Packages qualified as Packages import FloraWeb.Pages.Server.Search qualified as Search import FloraWeb.Pages.Server.Sessions qualified as Sessions import FloraWeb.Pages.Templates +import FloraWeb.Pages.Templates.Error (web404) import FloraWeb.Pages.Templates.Pages.Home qualified as Home import FloraWeb.Session import OddJobs.Endpoints qualified as OddJobs @@ -29,6 +30,7 @@ server cfg env = , packages = Packages.server , categories = Categories.server , search = Search.server + , notFound = serveNotFound } homeHandler :: FloraPage (Html ()) @@ -46,3 +48,6 @@ aboutHandler = do templateDefaults & #activeElements % #aboutNav .~ True render templateEnv Home.about + +serveNotFound :: FloraPage (Html ()) +serveNotFound = web404 diff --git a/src/web/FloraWeb/Pages/Server/Packages.hs b/src/web/FloraWeb/Pages/Server/Packages.hs index 9b32e94bc..aeb84e802 100644 --- a/src/web/FloraWeb/Pages/Server/Packages.hs +++ b/src/web/FloraWeb/Pages/Server/Packages.hs @@ -82,7 +82,7 @@ showPackageVersion :: Namespace -> PackageName -> Maybe Version -> FloraPage (Ht showPackageVersion namespace packageName mversion = do session <- getSession templateEnv' <- fromSession session defaultTemplateEnv - package <- guardThatPackageExists namespace packageName web404 + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) releases <- Query.getReleases (package.packageId) liftIO $ putStrLn $ "Number of releases: " <> show (length releases) let latestRelease = @@ -90,10 +90,7 @@ showPackageVersion namespace packageName mversion = do & Vector.filter (\r -> not (fromMaybe False r.deprecated)) & maximumBy (compare `on` (.version)) version = fromMaybe latestRelease.version mversion - release <- guardThatReleaseExists package.packageId version $ \_ -> - web404 - package.namespace - package.name + release <- guardThatReleaseExists package.packageId version $ const web404 numberOfReleases <- Query.getNumberOfReleases package.packageId dependents <- Query.getPackageDependents namespace packageName releaseDependencies <- Query.getRequirements release.releaseId @@ -150,7 +147,7 @@ showVersionDependentsHandler namespace packageName version Nothing = showVersion showVersionDependentsHandler namespace packageName version (Just pageNumber) = do session <- getSession templateEnv' <- fromSession session defaultTemplateEnv - _ <- guardThatPackageExists namespace packageName web404 + _ <- guardThatPackageExists namespace packageName (\_ _ -> web404) let templateEnv = templateEnv' { title = display namespace <> "/" <> display packageName @@ -169,7 +166,7 @@ showVersionDependentsHandler namespace packageName version (Just pageNumber) = d showDependenciesHandler :: Namespace -> PackageName -> FloraPage (Html ()) showDependenciesHandler namespace packageName = do - package <- guardThatPackageExists namespace packageName web404 + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) releases <- Query.getAllReleases (package.packageId) let latestRelease = maximumBy (compare `on` (.version)) releases showVersionDependenciesHandler namespace packageName latestRelease.version @@ -178,11 +175,8 @@ showVersionDependenciesHandler :: Namespace -> PackageName -> Version -> FloraPa showVersionDependenciesHandler namespace packageName version = do session <- getSession templateEnv' <- fromSession session defaultTemplateEnv - package <- guardThatPackageExists namespace packageName web404 - release <- guardThatReleaseExists package.packageId version $ \_ -> - web404 - package.namespace - package.name + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) + release <- guardThatReleaseExists package.packageId version $ const web404 let templateEnv = templateEnv' { title = display namespace <> "/" <> display packageName @@ -206,7 +200,7 @@ showVersionDependenciesHandler namespace packageName version = do showChangelogHandler :: Namespace -> PackageName -> FloraPage (Html ()) showChangelogHandler namespace packageName = do - package <- guardThatPackageExists namespace packageName web404 + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) releases <- Query.getAllReleases (package.packageId) let latestRelease = maximumBy (compare `on` (.version)) releases showVersionChangelogHandler namespace packageName (latestRelease.version) @@ -216,11 +210,8 @@ showVersionChangelogHandler namespace packageName version = do Log.logInfo_ $ display namespace session <- getSession templateEnv' <- fromSession session defaultTemplateEnv - package <- guardThatPackageExists namespace packageName web404 - release <- guardThatReleaseExists package.packageId version $ \_ -> - web404 - namespace - packageName + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) + release <- guardThatReleaseExists package.packageId version $ const web404 let templateEnv = templateEnv' { title = display namespace <> "/" <> display packageName @@ -233,7 +224,7 @@ listVersionsHandler :: Namespace -> PackageName -> FloraPage (Html ()) listVersionsHandler namespace packageName = do session <- getSession templateEnv' <- fromSession session defaultTemplateEnv - package <- guardThatPackageExists namespace packageName web404 + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) let templateEnv = templateEnv' { title = display namespace <> "/" <> display packageName diff --git a/src/web/FloraWeb/Pages/Templates/Error.hs b/src/web/FloraWeb/Pages/Templates/Error.hs index 87ad25e79..92af293e5 100644 --- a/src/web/FloraWeb/Pages/Templates/Error.hs +++ b/src/web/FloraWeb/Pages/Templates/Error.hs @@ -13,7 +13,6 @@ import Data.Kind (Type) import Effectful import Effectful.Error.Static (Error, throwError) import Effectful.Reader.Static (Reader) -import Flora.Model.Package.Types import FloraWeb.Pages.Templates import FloraWeb.Session import Servant (Header, Headers, ServerError (..)) @@ -41,10 +40,8 @@ web404 , IOE :> es , Reader (Headers '[Header "Set-Cookie" SetCookie] Session) :> es ) - => Namespace - -> PackageName - -> Eff es a -web404 _ _ = do + => Eff es a +web404 = do session <- getSession templateEnv <- fromSession session defaultTemplateEnv renderError templateEnv notFound404 From 3017aaefbf8e106c27dedd2c67b0700df2700f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Sun, 17 Sep 2023 12:47:36 +0200 Subject: [PATCH 2/2] Add changelog entry --- CHANGELOG.md | 3 ++- src/web/FloraWeb/Pages/Server/Packages.hs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f518d2c5d..9cfd4ed47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,16 @@ # CHANGELOG ## 1.0.13 -- XXXX-XX-XX -* Fixed text color for header and button in login page ([#418](https://github.com/flora-pm/flora-server/pull/418)) * Exclude deprecated releases from latest versions and search ([#373](https://github.com/flora-pm/flora-server/pull/373)) * Add namespace browsing ([#375](https://github.com/flora-pm/flora-server/pull/375)) * Overhaul the `nix` setup of flora and adjust the docs accordingly ([#369](https://github.com/flora-pm/flora-server/pull/369)) * Allow importing from index tarballs and incremental importing ([#387](https://github.com/flora-pm/flora-server/pull/387)) * Introduce a public API ([#415](https://github.com/flora-pm/flora-server/pull/415)) +* Fixed text color for header and button in login page ([#418](https://github.com/flora-pm/flora-server/pull/418)) * Fix mismatching OpenSearch names ([#427](https://github.com/flora-pm/flora-server/pull/427)) * Fix the margins of the search bar in mobile view ([#430](https://github.com/flora-pm/flora-server/pull/430)) * Have proper breadcrumbs for the package page title ([#431](https://github.com/flora-pm/flora-server/pull/431)) +* Configure the API gateway ([#432](https://github.com/flora-pm/flora-server/pull/432)) ## 1.0.12 -- 2023-04-04 diff --git a/src/web/FloraWeb/Pages/Server/Packages.hs b/src/web/FloraWeb/Pages/Server/Packages.hs index aeb84e802..b7eacf3fa 100644 --- a/src/web/FloraWeb/Pages/Server/Packages.hs +++ b/src/web/FloraWeb/Pages/Server/Packages.hs @@ -137,7 +137,7 @@ showPackageVersion namespace packageName mversion = do showDependentsHandler :: Namespace -> PackageName -> Maybe (Positive Word) -> FloraPage (Html ()) showDependentsHandler namespace packageName mPage = do - package <- guardThatPackageExists namespace packageName web404 + package <- guardThatPackageExists namespace packageName (\_ _ -> web404) releases <- Query.getAllReleases (package.packageId) let latestRelease = maximumBy (compare `on` (.version)) releases showVersionDependentsHandler namespace packageName latestRelease.version mPage