From a1a8d6f3eaac08b6e9181f1f7655ab4873456d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20=C4=8Cerm=C3=A1k?= Date: Mon, 18 Nov 2024 10:27:45 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20Use=20application=20default=20cr?= =?UTF-8?q?edentials=20as=20only=20authentication=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/web/src/pages/en/authentication.md | 67 ++++++------------- .../__tests__/spreadsheet-reader.test.ts | 34 ---------- .../core/src/reader/spreadsheet-reader.ts | 22 +----- packages/core/tsconfig.json | 3 +- 4 files changed, 23 insertions(+), 103 deletions(-) diff --git a/docs/web/src/pages/en/authentication.md b/docs/web/src/pages/en/authentication.md index 887bade5..a9a6168e 100644 --- a/docs/web/src/pages/en/authentication.md +++ b/docs/web/src/pages/en/authentication.md @@ -4,63 +4,36 @@ description: How to authenticate in Lokse layout: ../../layouts/MainLayout.astro --- -The last version of Google Spreadsheets API requires us to be authenticated to allow fetching spreadsheet data 🔑 +In order to fetch spreadsheet via `lokse update` command, you need to authenticate first. `lokse` uses [**Application default credential**](https://cloud.google.com/docs/authentication/provide-credentials-adc) – sign-in just with your Google account or provide service account. -There are three options for authentication: Service Account or API key. For each of these options we have to define some values as environment variables. +## Authenticate `lokse` locally (in your CLI): -## Environment variables +1. Install `gcloud` first: -We have practically two ways of how to define environment variables containing API key or Service Account credentials + https://cloud.google.com/sdk/docs/install -Use it before the command like +2. Sign-in with Google: -```sh -$ LOKSE_SERVICE_ACCOUNT_EMAIL=this_is_account_email LOKSE_PRIVATE_KEY=this_is_the_private_key lokse update -``` - -or use a more flexible and handy way of keeping variables inside the `.env.local` file. Create the file if you don't have it yet and put your variables into it like - -``` -LOKSE_SERVICE_ACCOUNT_EMAIL=this_is_account_email -LOKSE_PRIVATE_KEY=this_is_the_private_key -``` - -then you'll be able to run - -```sh -$ lokse update -``` + ```sh + gcloud auth application-default login --scopes=openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/drive.file + ``` -> For the sake of security reasons **Never check your API keys / secrets into version control**. That means you should **not forget to add `.env.local` into the `.gitignore`**. +3. Fetch spreadsheets: -## Service Account + ```sh + lokse update + ``` -Currently the best option for authentication is to create a Service account (if you don't have any, follow [the instructions here](https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication?id=service-account)) and then setup at least read permissions for your account in the spreadsheet. +4. In case of getting quote project warning: -Since every Service account contains email adress just click the "Share" button at top right corner of the spreadsheet and add your Service account email there. + ```sh + gcloud auth application-default set-quota-project + ``` -Once you have the Service account created, you should have its client email and private key. It looks smilar to this +## Authentication `lokse` in CI pipeline: -``` -"client_email": "localize-with-spreadsheet@localize-with-spreadsheet.iam.gserviceaccount.com", -"private_key": "-----BEGIN PRIVATE KEY-----\nAnd_here_is_a_long_text_of_random_characters_that_defines_the_private_key\n-----END PRIVATE KEY-----\n", -``` - -Take these two values, put them into `LOKSE_SERVICE_ACCOUNT_EMAIL` and `LOKSE_PRIVATE_KEY` variables using one of two ways [described above](#environment-variables) and there you go, fetching data from spreadsheet should work now. - -## API key - -For read only access, we're good with usage of API key, if you don't have any, follow [the instructions here](https://theoephraim.github.io/node-google-spreadsheet/#/getting-started/authentication?id=api-key) to create one. +https://cloud.google.com/docs/authentication/provide-credentials-adc: -Then define the variable `LOKSE_API_KEY=this_is_your_api_key` and then if the key is valid fetching data should work for you. - -Using API key instead of Service account has one important limitation: You spreadsheet must set permissions to be visible for everyone in the Internet. - -## Application default credential - -If none of those environment variables have been provided, `lokse` fallbacks to [application default credential authentication](https://cloud.google.com/docs/authentication/provide-credentials-adc). -Don't forget to login first with appropriate scopes: - -```bash -gcloud auth application-default login --scopes=openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/drive.file +```sh +export GOOGLE_APPLICATION_CREDENTIALS="SERVICE_ACCOUNT_KEY_PATH" ``` diff --git a/packages/core/src/reader/__tests__/spreadsheet-reader.test.ts b/packages/core/src/reader/__tests__/spreadsheet-reader.test.ts index 7762e3a4..1c7b9e56 100644 --- a/packages/core/src/reader/__tests__/spreadsheet-reader.test.ts +++ b/packages/core/src/reader/__tests__/spreadsheet-reader.test.ts @@ -35,40 +35,6 @@ describe('SpreadsheetReader', () => { GoogleSpreadsheetMock.mockClear(); }); - afterEach(() => { - delete process.env.LOKSE_API_KEY; - delete process.env.LOKSE_SERVICE_ACCOUNT_EMAIL; - delete process.env.LOKSE_PRIVATE_KEY; - }); - - it('uses service account if available', async () => { - const private_key = 'this-is-dummy-private-key'; - const client_email = 'this-is@dummy-email'; - - process.env.LOKSE_SERVICE_ACCOUNT_EMAIL = client_email; - process.env.LOKSE_PRIVATE_KEY = private_key; - - const reader = new SpreadsheetReader('test-sheet-id', new WorksheetReader('*'), noPlugins); - - const client = await reader.authenticate(); - - // @ts-expect-error private property - expect(client._clientId).toEqual(client_email); - // @ts-expect-error private property - expect(client._clientSecret).toEqual(private_key); - }); - - it('uses api key if available', async () => { - const dummyApiKey = 'dummy-api-key'; - process.env.LOKSE_API_KEY = dummyApiKey; - - const reader = new SpreadsheetReader('test-sheet-id', new WorksheetReader('*'), noPlugins); - - const client = await reader.authenticate(); - - expect(client.apiKey).toEqual(dummyApiKey); - }); - it('throw if service account nor api key found', async () => { const reader = new SpreadsheetReader('test-sheet-id', new WorksheetReader('*'), noPlugins); diff --git a/packages/core/src/reader/spreadsheet-reader.ts b/packages/core/src/reader/spreadsheet-reader.ts index 0bb35ec9..d8dd44f0 100644 --- a/packages/core/src/reader/spreadsheet-reader.ts +++ b/packages/core/src/reader/spreadsheet-reader.ts @@ -1,5 +1,6 @@ +/* eslint-disable camelcase */ import { GoogleSpreadsheet } from 'google-spreadsheet'; -import { GoogleAuth, JWT } from 'google-auth-library'; +import { GoogleAuth } from 'google-auth-library'; import Line from '../line'; import { FatalError, getErrorMessage } from '../errors'; @@ -36,25 +37,6 @@ export class SpreadsheetReader { } createAuthClient() { - const { LOKSE_API_KEY, LOKSE_SERVICE_ACCOUNT_EMAIL, LOKSE_PRIVATE_KEY } = process.env; - - if (LOKSE_SERVICE_ACCOUNT_EMAIL && LOKSE_PRIVATE_KEY) { - this.logger.log('🔑 Authenticating with service account...'); - - const jwt = new JWT({ - clientId: LOKSE_SERVICE_ACCOUNT_EMAIL, - clientSecret: LOKSE_PRIVATE_KEY, - }); - - return new GoogleAuth({ authClient: jwt }); - } - - if (LOKSE_API_KEY) { - this.logger.log('🔑 Authenticating with API key...'); - - return new GoogleAuth({ apiKey: LOKSE_API_KEY }); - } - this.logger.log('🔑 Authenticating with Application Default Credentials...'); return new GoogleAuth({ diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index cd2f4a2f..59114198 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "lib", - "rootDir": "src", - "skipLibCheck": true + "rootDir": "src" }, "include": [ "src/**/*",