Skip to content

Commit

Permalink
Merge pull request #90 from spreadshirt/bump-backstage
Browse files Browse the repository at this point in the history
Bump backstage to 1.25.0
  • Loading branch information
ivangonzalezacuna authored Apr 8, 2024
2 parents d133f1c + de0b7d8 commit fd31b0d
Show file tree
Hide file tree
Showing 29 changed files with 1,118 additions and 767 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-jars-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@spreadshirt/backstage-plugin-s3-viewer-backend': patch
---

Fix typo in the documentation
8 changes: 8 additions & 0 deletions .changeset/famous-doors-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@spreadshirt/backstage-plugin-s3-viewer': patch
'@spreadshirt/backstage-plugin-s3-viewer-backend': patch
'@spreadshirt/backstage-plugin-s3-viewer-common': patch
'@spreadshirt/backstage-plugin-s3-viewer-node': patch
---

Bump backstage dependencies to version 1.25.0
6 changes: 6 additions & 0 deletions .changeset/fluffy-turkeys-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@spreadshirt/backstage-plugin-s3-viewer': patch
---

Added new method to the s3-viewer API, which will be responsible of setting up
the cookie required to download or preview data in the UI.
10 changes: 10 additions & 0 deletions .changeset/perfect-lies-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@spreadshirt/backstage-plugin-s3-viewer-backend': minor
---

**BREAKING**: Migrate backend plugin to use the new auth service.

No changes are required if running in the new backend system.

In case you're still using the old backend system you'll need to make sure the
new `auth` and `httpAuth` are sent, while the `identity` and `tokenManager` are not needed any longer.
9 changes: 9 additions & 0 deletions .changeset/rich-spiders-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@spreadshirt/backstage-plugin-s3-viewer-backend': minor
'@spreadshirt/backstage-plugin-s3-viewer-common': minor
---

**BREAKING**: Replace `setTokenCookie` with new method integrated into the S3Api `setCookie()`.

Due to the new authentication backend provided by Backstage in the version 1.24.0, we
can now use this endpoint and simplify the whole setup.
5 changes: 5 additions & 0 deletions .changeset/tiny-camels-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@spreadshirt/backstage-plugin-s3-viewer-backend': patch
---

Use new `PermissionsService` type in the backend instead of the deprecated `PermissionEvaluator`
10 changes: 10 additions & 0 deletions .changeset/warm-rocks-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@spreadshirt/backstage-plugin-s3-viewer-backend': minor
'@spreadshirt/backstage-plugin-s3-viewer-node': minor
---

**BREAKING**: Remove the `middleware` from the s3-viewer.

With the newly authentication backend system, the middleware is not needed any longer,
so it can be completely removed instead of keeping it here. _NOTE_ that using this
`s3-viewer` version will require you to be up-to-date with the latest Backstage version as well.
2 changes: 1 addition & 1 deletion backstage.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"version": "1.23.1"
"version": "1.25.0"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"npm:release": "yarn install && tsc && yarn build:all && changeset publish"
},
"devDependencies": {
"@backstage/cli": "^0.25.2",
"@backstage/cli": "^0.26.2",
"@changesets/cli": "^2.24.4",
"@spotify/prettier-config": "^12.0.0",
"@types/react": "^18.0.2",
Expand Down
47 changes: 18 additions & 29 deletions plugins/s3-viewer-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ To get started, follow these steps:
env: PluginEnvironment,
): Promise<Router> {
const { router } = await S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).build();
return router;
}
Expand All @@ -60,7 +60,7 @@ To get started, follow these steps:
@@ -63,6 +65,7 @@ async function main() {
const apiRouter = Router();
apiRouter.use('/catalog', await catalog(catalogEnv));
+ apiRouter.use('/s3', await s3(s3Env));
+ apiRouter.use('/s3-viewer', await s3(s3Env));
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
```
Expand Down Expand Up @@ -101,9 +101,6 @@ backend.add(s3ViewerExtensions());
The `extensions` type contains all the needed functions to override any of the elements that are defined in the next section.
To enable the permissionMiddleware, which is needed when used together with the permissions setup, you can do it using the `app-config.yaml`
by setting `s3.permissionMiddleware` to `true`.
## Configuration
This plugin allows fetching the buckets from different endpoints and using different approaches. This is a full example entry in `app-config.yaml`:
Expand Down Expand Up @@ -149,7 +146,6 @@ s3:
bucketRefreshSchedule:
frequency: { minutes: 30 }
timeout: { minutes: 1 }
permissionMiddleware: true
```
### bucketLocatorMethods
Expand Down Expand Up @@ -181,13 +177,13 @@ It is also possible to create a new CredentialsProvider if that is required for
```typescript
const builder = S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).setCredentialsProvider(new CustomCredentialsProvider());
const { router } = await builder.build();
Expand Down Expand Up @@ -229,10 +225,6 @@ To achieve that you need to specify the __platform name__ and then an array of b
If set, the buckets provider will be executed with the defined schedule.
### permissionMiddleware
Used by the new backend system. This field is optional. If set to true, the permissionMiddleware will be enabled in the backend plugin.
## Customization
Apart from the custom `CredentialsProvider`, it is also possible to make more changes to the plugin, so that it can match your internal requirements.
Expand All @@ -243,13 +235,13 @@ First of all, the client used to communicate with the S3 buckets can be overwrit
```typescript
const builder = S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).setClient(new CustomS3Client());
const { router } = await builder.build();
Expand All @@ -263,13 +255,13 @@ It is responsible for fetching all the bucket information for the obtained platf
```typescript
const builder = S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).setBucketsProvider(new CustomBucketsProvider());
const { router } = await builder.build();
Expand All @@ -281,13 +273,13 @@ By default, the S3 API doesn't provide a straightforward way to fetch informatio
```typescript
const builder = S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).setBucketStatsProvider(new CustomBucketStatsProvider());
const { router } = await builder.build();
Expand All @@ -306,27 +298,28 @@ s3:
## Permissions Setup
The information present in the S3 buckets can be dangerous to be shared with all the Backstage users. Therefore, the permissions setup is needed. To make it work, every request to this plugin needs to have an `Authorization` header or a cookie called `s3_viewer_token`. Due to the current design, some requests cannot add the header properly, so the way to solve this issue is to enable a middleware. First, note that the [service-to-service auth](https://backstage.io/docs/auth/service-to-service-auth) is needed. Then, a few steps need to be followed to fully support this feature:
The information present in the S3 buckets can be dangerous to be shared with all the Backstage users. Therefore, the permissions setup is needed. To make it work every request to this plugin needs to be authenticated. Most cases are already handled by the authentication service provided by Backstage.
However, the preview and download of data from S3 require the Backstage `user-cookie` to be set as the requests come directly from browser interactions (`img` element and downloads) and those can't set the token using the fetchApi. The sign in has to be extended to make sure the cookie is set for the s3-viewer:
1. Customize the `SignInPage` to add a token as soon as a user is logged in:
```typescript
// In packages/app/src/App.tsx
// ...
import { setTokenCookie } from '@spreadshirt/backstage-plugin-s3-viewer-common';
import { S3ApiRef } from '@spreadshirt/backstage-plugin-s3-viewer';
const app = createApp({
// ...
components: {
SignInPage: props => {
const discoveryApi = useApi(discoveryApiRef);
const s3ViewerApi = useApi(S3ApiRef);
return (
<SignInPage // Or ProxiedSignInPage
{...props}
providers={['guest', 'custom', ...providers]}
onSignInSuccess={async (identityApi: IdentityApi) => {
await setTokenCookie(discoveryApi, identityApi);
props.onSignInSuccess(identityApi);
await s3ViewerApi.setCookie();
}}
/>
);
Expand All @@ -340,22 +333,18 @@ The information present in the S3 buckets can be dangerous to be shared with all
2. Then, enable this feature in the backend. For that, add this function before the `build()` step:
```typescript
const builder = S3Builder.createBuilder({
auth: env.auth,
config: env.config,
logger: env.logger,
scheduler: env.scheduler,
discovery: env.discovery,
identity: env.identity,
permissions: env.permissions,
tokenManager: env.tokenManager,
httpAuth: env.httpAuth,
}).useMiddleware();
const { router } = await builder.build();
```
3. If needed, the `useMiddleware` function allows you to inject a custom middleware, in case you need to execute something else. By default, it will use a middleware like the one defined [here](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/authenticate-api-requests.md).
**NOTE**: The usage of the middleware is meant to be used in production environments (when `NODE_ENV` is set to `production`). If you're working in development with a `guest` user, please set this environment variable to another value (like `development`), so the authorization won't fail due to an invalid token.
Once this setup is done, you will need to extend the permission policy to check for the available permissions and `ALLOW` or `DENY` access to any data you want. This step is completely up to the end user, as the way of obtaining these permissions might differ for every company. The following example would allow listing all the buckets and keys, but deny downloading and previewing the objects:
```typescript
Expand Down
6 changes: 0 additions & 6 deletions plugins/s3-viewer-backend/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,5 @@ export interface Config {
*/
buckets: Array<string>;
}>;
/**
* If set to `true` the permissionMiddleware will be enabled. The default one will be used, but it can be customized.
* The permissionMiddleware is required if the permissions setup is used.
* @visibility backend
*/
permissionMiddleware?: boolean;
};
}
24 changes: 12 additions & 12 deletions plugins/s3-viewer-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@
"@aws-sdk/client-s3": "^3.350.0",
"@aws-sdk/protocol-http": "^3.347.0",
"@aws-sdk/signature-v4": "^3.347.0",
"@backstage/backend-common": "^0.21.0",
"@backstage/backend-plugin-api": "^0.6.10",
"@backstage/backend-tasks": "^0.5.15",
"@backstage/config": "^1.1.1",
"@backstage/errors": "^1.2.3",
"@backstage/plugin-auth-node": "^0.4.5",
"@backstage/plugin-permission-backend": "^0.5.33",
"@backstage/plugin-permission-common": "^0.7.12",
"@backstage/plugin-permission-node": "^0.7.21",
"@backstage/backend-common": "^0.21.6",
"@backstage/backend-plugin-api": "^0.6.16",
"@backstage/backend-tasks": "^0.5.21",
"@backstage/config": "^1.2.0",
"@backstage/errors": "^1.2.4",
"@backstage/plugin-auth-node": "^0.4.11",
"@backstage/plugin-permission-backend": "^0.5.40",
"@backstage/plugin-permission-common": "^0.7.13",
"@backstage/plugin-permission-node": "^0.7.27",
"@backstage/types": "^1.1.1",
"@spreadshirt/backstage-plugin-s3-viewer-common": "^0.4.0",
"@spreadshirt/backstage-plugin-s3-viewer-node": "0.1.0",
Expand All @@ -51,16 +51,16 @@
"cross-fetch": "^4.0.0",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"jose": "^4.6.0",
"knex": "^3.0.0",
"moment": "^2.29.4",
"stream": "^0.0.2",
"yn": "^4.0.0",
"zod": "^3.21.4"
},
"devDependencies": {
"@backstage/cli": "^0.25.2",
"@backstage/test-utils": "^1.5.0",
"@backstage/backend-test-utils": "^0.3.6",
"@backstage/cli": "^0.26.2",
"@backstage/test-utils": "^1.5.3",
"@types/cookie-parser": "^1.4.3",
"@types/jest": "*",
"@types/supertest": "^2.0.8",
Expand Down
1 change: 0 additions & 1 deletion plugins/s3-viewer-backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

export * from './service';
export * from './middleware';
export {
createS3ViewerBucketsConditionalDecision,
s3ViewerBucketConditions,
Expand Down
1 change: 0 additions & 1 deletion plugins/s3-viewer-backend/src/middleware/index.ts

This file was deleted.

Loading

0 comments on commit fd31b0d

Please sign in to comment.