From af4c1f08ec73b82edcabc534b8f474e3b93352ec Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Tue, 27 Aug 2024 12:44:14 +0000 Subject: [PATCH] feat: write POST /v1/admin/apps/:key/config --- .../api/v1/admin/apps/create-config.ee.js | 30 ++++++++++ .../v1/admin/apps/create-config.ee.test.js | 58 +++++++++++++++++++ .../src/routes/api/v1/admin/apps.ee.js | 10 ++++ .../rest/api/v1/admin/apps/create-config.js | 19 ++++++ 4 files changed, 117 insertions(+) create mode 100644 packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js create mode 100644 packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js create mode 100644 packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js diff --git a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js new file mode 100644 index 00000000..5e5d374a --- /dev/null +++ b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.js @@ -0,0 +1,30 @@ +import { renderError, renderObject } from '../../../../../helpers/renderer.js'; +import AppConfig from '../../../../../models/app-config.js'; + +export default async (request, response) => { + const appKey = request.params.appKey; + + const appConfig = await AppConfig.query() + .findOne({ key: appKey }); + + if (appConfig) { + return renderError(response, [{ general: ['App config already exists.'] }], 409); + } + + const createdAppConfig = await AppConfig + .query() + .insertAndFetch(appConfigParams(request)); + + renderObject(response, createdAppConfig, { status: 201 }); +}; + +const appConfigParams = (request) => { + const { allowCustomConnection, shared, disabled } = request.body; + + return { + key: request.params.appKey, + allowCustomConnection, + shared, + disabled, + }; +}; diff --git a/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js new file mode 100644 index 00000000..839f6fb2 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/admin/apps/create-config.ee.test.js @@ -0,0 +1,58 @@ +import { vi, describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; + +import app from '../../../../../app.js'; +import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js'; +import { createUser } from '../../../../../../test/factories/user.js'; +import { createRole } from '../../../../../../test/factories/role.js'; +import createAppConfigMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-config.js'; +import { createAppConfig } from '../../../../../../test/factories/app-config.js'; +import * as license from '../../../../../helpers/license.ee.js'; + +describe('POST /api/v1/admin/apps/:appKey/config', () => { + let currentUser, adminRole, token; + + beforeEach(async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + adminRole = await createRole({ key: 'admin' }); + currentUser = await createUser({ roleId: adminRole.id }); + + token = await createAuthTokenByUserId(currentUser.id); + }); + + it('should return created app config', async () => { + const appConfig = { + key: 'gitlab', + allowCustomConnection: true, + shared: true, + disabled: false, + }; + + const response = await request(app) + .post('/api/v1/admin/apps/gitlab/config') + .set('Authorization', token) + .send(appConfig) + .expect(201); + + const expectedPayload = createAppConfigMock(appConfig); + expect(response.body).toMatchObject(expectedPayload); + }); + + it('should return HTTP 409 for already existing app config', async () => { + const appConfig = { + key: 'gitlab', + allowCustomConnection: true, + shared: true, + disabled: false, + }; + + await createAppConfig(appConfig); + + await request(app) + .post('/api/v1/admin/apps/gitlab/config') + .set('Authorization', token) + .send(appConfig) + .expect(409); + }); +}); diff --git a/packages/backend/src/routes/api/v1/admin/apps.ee.js b/packages/backend/src/routes/api/v1/admin/apps.ee.js index 2a87f8ac..554e8e92 100644 --- a/packages/backend/src/routes/api/v1/admin/apps.ee.js +++ b/packages/backend/src/routes/api/v1/admin/apps.ee.js @@ -3,12 +3,22 @@ import asyncHandler from 'express-async-handler'; import { authenticateUser } from '../../../../helpers/authentication.js'; import { authorizeAdmin } from '../../../../helpers/authorization.js'; import { checkIsEnterprise } from '../../../../helpers/check-is-enterprise.js'; +import createConfigAction from '../../../../controllers/api/v1/admin/apps/create-config.ee.js'; import getAuthClientsAction from '../../../../controllers/api/v1/admin/apps/get-auth-clients.ee.js'; import getAuthClientAction from '../../../../controllers/api/v1/admin/apps/get-auth-client.ee.js'; import createAuthClientAction from '../../../../controllers/api/v1/admin/apps/create-auth-client.ee.js'; const router = Router(); + +router.post( + '/:appKey/config', + authenticateUser, + authorizeAdmin, + checkIsEnterprise, + asyncHandler(createConfigAction) +); + router.get( '/:appKey/auth-clients', authenticateUser, diff --git a/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js b/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js new file mode 100644 index 00000000..a1c1aad4 --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/admin/apps/create-config.js @@ -0,0 +1,19 @@ +const createAppConfigMock = (appConfig) => { + return { + data: { + key: appConfig.key, + allowCustomConnection: appConfig.allowCustomConnection, + shared: appConfig.shared, + disabled: appConfig.disabled, + }, + meta: { + count: 1, + currentPage: null, + isArray: false, + totalPages: null, + type: 'AppConfig', + }, + }; +}; + +export default createAppConfigMock;