aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/api
diff options
context:
space:
mode:
authorWouter Admiraal <wouter.admiraal@sonarsource.com>2023-02-14 10:59:50 +0100
committersonartech <sonartech@sonarsource.com>2023-02-20 20:03:01 +0000
commitedc84dc653f5cc208bf071f325b08334ad1bddc8 (patch)
tree6d85b21e2ac8ff6745fdc7a8b8d8b3fcdf975c3e /server/sonar-web/src/main/js/api
parente16a504c67e6ee38757e8fc4899e336b4f3c0cda (diff)
downloadsonarqube-edc84dc653f5cc208bf071f325b08334ad1bddc8.tar.gz
sonarqube-edc84dc653f5cc208bf071f325b08334ad1bddc8.zip
SONAR-17810 Use Visibility enum instead of hard-coded strings
Diffstat (limited to 'server/sonar-web/src/main/js/api')
-rw-r--r--server/sonar-web/src/main/js/api/components.ts8
-rw-r--r--server/sonar-web/src/main/js/api/mocks/PermissionTemplateServiceMock.ts191
-rw-r--r--server/sonar-web/src/main/js/api/mocks/PermissionsServiceMock.ts389
-rw-r--r--server/sonar-web/src/main/js/api/permissions.ts4
4 files changed, 397 insertions, 195 deletions
diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts
index 85aa9e48933..ddecc845d70 100644
--- a/server/sonar-web/src/main/js/api/components.ts
+++ b/server/sonar-web/src/main/js/api/components.ts
@@ -20,7 +20,12 @@
import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
import { BranchParameters } from '../types/branch-like';
-import { ComponentQualifier, TreeComponent, TreeComponentWithPath } from '../types/component';
+import {
+ ComponentQualifier,
+ TreeComponent,
+ TreeComponentWithPath,
+ Visibility,
+} from '../types/component';
import {
ComponentMeasure,
Dict,
@@ -31,7 +36,6 @@ import {
Paging,
SourceLine,
SourceViewerFile,
- Visibility,
} from '../types/types';
export interface BaseSearchProjectsParameters {
diff --git a/server/sonar-web/src/main/js/api/mocks/PermissionTemplateServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/PermissionTemplateServiceMock.ts
deleted file mode 100644
index d93999a7434..00000000000
--- a/server/sonar-web/src/main/js/api/mocks/PermissionTemplateServiceMock.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { chunk, cloneDeep } from 'lodash';
-import {
- mockPermissionTemplate,
- mockTemplateGroup,
- mockTemplateUser,
-} from '../../helpers/testMocks';
-import { PermissionTemplate } from '../../types/types';
-import { BaseSearchProjectsParameters } from '../components';
-import {
- addProjectCreatorToTemplate,
- bulkApplyTemplate,
- getPermissionTemplateGroups,
- getPermissionTemplates,
- getPermissionTemplateUsers,
- grantTemplatePermissionToGroup,
- grantTemplatePermissionToUser,
- removeProjectCreatorFromTemplate,
- revokeTemplatePermissionFromGroup,
- revokeTemplatePermissionFromUser,
-} from '../permissions';
-
-const MAX_PROJECTS_TO_APPLY_PERMISSION_TEMPLATE = 10;
-
-const defaultPermissionTemplates: PermissionTemplate[] = [
- mockPermissionTemplate(),
- mockPermissionTemplate({
- id: 'template2',
- name: 'Permission Template 2',
- }),
-];
-
-const templateUsers = [
- mockTemplateUser(),
- mockTemplateUser({
- login: 'gooduser1',
- name: 'John',
- permissions: ['issueadmin', 'securityhotspotadmin', 'user'],
- }),
- mockTemplateUser({
- login: 'gooduser2',
- name: 'Alexa',
- permissions: ['issueadmin', 'user'],
- }),
- mockTemplateUser({
- name: 'Siri',
- login: 'gooduser3',
- }),
- mockTemplateUser({
- login: 'gooduser4',
- name: 'Cool',
- permissions: ['user'],
- }),
- mockTemplateUser({
- name: 'White',
- login: 'baduser1',
- }),
- mockTemplateUser({
- name: 'Green',
- login: 'baduser2',
- }),
-];
-
-const templateGroups = [
- mockTemplateGroup(),
- mockTemplateGroup({ id: 'admins', name: 'admins', permissions: [] }),
-];
-
-const PAGE_SIZE = 5;
-const MIN_QUERY_LENGTH = 3;
-const DEFAULT_PAGE = 1;
-
-jest.mock('../permissions');
-
-export default class PermissionTemplateServiceMock {
- permissionTemplates: PermissionTemplate[] = [];
- isAllowedPermissionChange = true;
-
- constructor() {
- this.permissionTemplates = cloneDeep(defaultPermissionTemplates);
- (getPermissionTemplates as jest.Mock).mockImplementation(this.handleGetPermissionTemplates);
- (bulkApplyTemplate as jest.Mock).mockImplementation(this.handleBulkApplyTemplate);
- (getPermissionTemplateUsers as jest.Mock).mockImplementation(
- this.handleGetPermissionTemplateUsers
- );
- (getPermissionTemplateGroups as jest.Mock).mockImplementation(
- this.handleGetPermissionTemplateGroups
- );
- (addProjectCreatorToTemplate as jest.Mock).mockImplementation(this.handlePermissionChange);
- (removeProjectCreatorFromTemplate as jest.Mock).mockImplementation(this.handlePermissionChange);
- (grantTemplatePermissionToGroup as jest.Mock).mockImplementation(this.handlePermissionChange);
- (revokeTemplatePermissionFromGroup as jest.Mock).mockImplementation(
- this.handlePermissionChange
- );
- (grantTemplatePermissionToUser as jest.Mock).mockImplementation(this.handlePermissionChange);
- (revokeTemplatePermissionFromUser as jest.Mock).mockImplementation(this.handlePermissionChange);
- }
-
- handleGetPermissionTemplates = () => {
- return this.reply({ permissionTemplates: this.permissionTemplates });
- };
-
- handleBulkApplyTemplate = (params: BaseSearchProjectsParameters) => {
- if (
- params.projects &&
- params.projects.split(',').length > MAX_PROJECTS_TO_APPLY_PERMISSION_TEMPLATE
- ) {
- const response = new Response(
- JSON.stringify({ errors: [{ msg: 'bulk apply permission template error message' }] })
- );
- return Promise.reject(response);
- }
-
- return Promise.resolve();
- };
-
- handleGetPermissionTemplateUsers = (data: { q?: string | null; p?: number; ps?: number }) => {
- const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q } = data;
-
- const users =
- q && q.length >= MIN_QUERY_LENGTH
- ? templateUsers.filter((user) =>
- [user.login, user.name].some((key) => key.toLowerCase().includes(q.toLowerCase()))
- )
- : templateUsers;
-
- const usersChunks = chunk(users, ps);
-
- return this.reply({
- paging: { pageSize: ps, total: users.length, pageIndex: p },
- users: usersChunks[p - 1] ?? [],
- });
- };
-
- handleGetPermissionTemplateGroups = (data: {
- templateId: string;
- q?: string | null;
- permission?: string;
- p?: number;
- ps?: number;
- }) => {
- const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q } = data;
-
- const groups =
- q && q.length >= MIN_QUERY_LENGTH
- ? templateGroups.filter((group) => group.name.toLowerCase().includes(q.toLowerCase()))
- : templateGroups;
-
- const groupsChunks = chunk(groups, ps);
-
- return this.reply({
- paging: { pageSize: ps, total: groups.length, pageIndex: p },
- groups: groupsChunks[p - 1] ?? [],
- });
- };
-
- handlePermissionChange = () => {
- return this.isAllowedPermissionChange ? Promise.resolve() : Promise.reject();
- };
-
- updatePermissionChangeAllowance = (val: boolean) => {
- this.isAllowedPermissionChange = val;
- };
-
- reset = () => {
- this.permissionTemplates = cloneDeep(defaultPermissionTemplates);
- this.updatePermissionChangeAllowance(true);
- };
-
- reply<T>(response: T): Promise<T> {
- return Promise.resolve(cloneDeep(response));
- }
-}
diff --git a/server/sonar-web/src/main/js/api/mocks/PermissionsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/PermissionsServiceMock.ts
new file mode 100644
index 00000000000..96531f55e5c
--- /dev/null
+++ b/server/sonar-web/src/main/js/api/mocks/PermissionsServiceMock.ts
@@ -0,0 +1,389 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { chunk, cloneDeep, remove, uniq } from 'lodash';
+import {
+ mockPermission,
+ mockPermissionGroup,
+ mockPermissionTemplate,
+ mockPermissionUser,
+ mockTemplateGroup,
+ mockTemplateUser,
+} from '../../helpers/mocks/permissions';
+import { ComponentQualifier, Visibility } from '../../types/component';
+import { Permissions } from '../../types/permissions';
+import { Permission, PermissionGroup, PermissionTemplate, PermissionUser } from '../../types/types';
+import { BaseSearchProjectsParameters } from '../components';
+import {
+ addProjectCreatorToTemplate,
+ applyTemplateToProject,
+ bulkApplyTemplate,
+ changeProjectVisibility,
+ getPermissionsGroupsForComponent,
+ getPermissionsUsersForComponent,
+ getPermissionTemplateGroups,
+ getPermissionTemplates,
+ getPermissionTemplateUsers,
+ grantPermissionToGroup,
+ grantPermissionToUser,
+ grantTemplatePermissionToGroup,
+ grantTemplatePermissionToUser,
+ removeProjectCreatorFromTemplate,
+ revokePermissionFromGroup,
+ revokePermissionFromUser,
+ revokeTemplatePermissionFromGroup,
+ revokeTemplatePermissionFromUser,
+} from '../permissions';
+
+const MAX_PROJECTS_TO_APPLY_PERMISSION_TEMPLATE = 10;
+
+const defaultPermissionTemplates: PermissionTemplate[] = [
+ mockPermissionTemplate(),
+ mockPermissionTemplate({
+ id: 'template2',
+ name: 'Permission Template 2',
+ }),
+];
+
+const templateUsers = [
+ mockTemplateUser(),
+ mockTemplateUser({
+ login: 'gooduser1',
+ name: 'John',
+ permissions: ['issueadmin', 'securityhotspotadmin', 'user'],
+ }),
+ mockTemplateUser({
+ login: 'gooduser2',
+ name: 'Alexa',
+ permissions: ['issueadmin', 'user'],
+ }),
+ mockTemplateUser({
+ name: 'Siri',
+ login: 'gooduser3',
+ }),
+ mockTemplateUser({
+ login: 'gooduser4',
+ name: 'Cool',
+ permissions: ['user'],
+ }),
+ mockTemplateUser({
+ name: 'White',
+ login: 'baduser1',
+ }),
+ mockTemplateUser({
+ name: 'Green',
+ login: 'baduser2',
+ }),
+];
+
+const templateGroups = [
+ mockTemplateGroup(),
+ mockTemplateGroup({ id: 'admins', name: 'admins', permissions: [] }),
+];
+
+const defaultUsers = [mockPermissionUser()];
+
+const defaultGroups = [
+ mockPermissionGroup({ name: 'sonar-users', permissions: [Permissions.Browse] }),
+ mockPermissionGroup({
+ name: 'sonar-admins',
+ permissions: [Permissions.Admin, Permissions.Browse],
+ }),
+ mockPermissionGroup({ name: 'sonar-losers', permissions: [] }),
+];
+
+const PAGE_SIZE = 5;
+const MIN_QUERY_LENGTH = 3;
+const DEFAULT_PAGE = 1;
+
+jest.mock('../permissions');
+
+export default class PermissionsServiceMock {
+ permissionTemplates: PermissionTemplate[] = [];
+ permissions: Permission[];
+ defaultTemplates: Array<{ templateId: string; qualifier: string }>;
+ groups: PermissionGroup[];
+ users: PermissionUser[];
+ isAllowedPermissionChange = true;
+
+ constructor() {
+ this.permissionTemplates = cloneDeep(defaultPermissionTemplates);
+ this.defaultTemplates = [
+ ComponentQualifier.Project,
+ ComponentQualifier.Application,
+ ComponentQualifier.Portfolio,
+ ].map((qualifier) => ({ templateId: this.permissionTemplates[0].id, qualifier }));
+ this.permissions = [
+ Permissions.Admin,
+ Permissions.CodeViewer,
+ Permissions.IssueAdmin,
+ Permissions.SecurityHotspotAdmin,
+ Permissions.Scan,
+ Permissions.Browse,
+ ].map((key) => mockPermission({ key, name: key }));
+ this.groups = cloneDeep(defaultGroups);
+ this.users = cloneDeep(defaultUsers);
+
+ jest.mocked(getPermissionTemplates).mockImplementation(this.handleGetPermissionTemplates);
+ jest.mocked(bulkApplyTemplate).mockImplementation(this.handleBulkApplyTemplate);
+ jest.mocked(applyTemplateToProject).mockImplementation(this.handleApplyTemplateToProject);
+ jest
+ .mocked(getPermissionTemplateUsers)
+ .mockImplementation(this.handleGetPermissionTemplateUsers);
+ jest
+ .mocked(getPermissionTemplateGroups)
+ .mockImplementation(this.handleGetPermissionTemplateGroups);
+ jest.mocked(addProjectCreatorToTemplate).mockImplementation(this.handlePermissionChange);
+ jest.mocked(removeProjectCreatorFromTemplate).mockImplementation(this.handlePermissionChange);
+ jest.mocked(grantTemplatePermissionToGroup).mockImplementation(this.handlePermissionChange);
+ jest.mocked(revokeTemplatePermissionFromGroup).mockImplementation(this.handlePermissionChange);
+ jest.mocked(grantTemplatePermissionToUser).mockImplementation(this.handlePermissionChange);
+ jest.mocked(revokeTemplatePermissionFromUser).mockImplementation(this.handlePermissionChange);
+ jest.mocked(changeProjectVisibility).mockImplementation(this.handleChangeProjectVisibility);
+ jest
+ .mocked(getPermissionsGroupsForComponent)
+ .mockImplementation(this.handleGetPermissionGroupsForComponent);
+ jest
+ .mocked(getPermissionsUsersForComponent)
+ .mockImplementation(this.handleGetPermissionUsersForComponent);
+ jest.mocked(grantPermissionToGroup).mockImplementation(this.handleGrantPermissionToGroup);
+ jest.mocked(revokePermissionFromGroup).mockImplementation(this.handleRevokePermissionFromGroup);
+ jest.mocked(grantPermissionToUser).mockImplementation(this.handleGrantPermissionToUser);
+ jest.mocked(revokePermissionFromUser).mockImplementation(this.handleRevokePermissionFromUser);
+ }
+
+ handleGetPermissionTemplates = () => {
+ return this.reply({
+ permissionTemplates: this.permissionTemplates,
+ defaultTemplates: this.defaultTemplates,
+ permissions: this.permissions,
+ });
+ };
+
+ handleApplyTemplateToProject = (_data: { projectKey: string; templateId: string }) => {
+ return this.reply(undefined);
+ };
+
+ handleBulkApplyTemplate = (params: BaseSearchProjectsParameters) => {
+ if (
+ params.projects &&
+ params.projects.split(',').length > MAX_PROJECTS_TO_APPLY_PERMISSION_TEMPLATE
+ ) {
+ const response = new Response(
+ JSON.stringify({ errors: [{ msg: 'bulk apply permission template error message' }] })
+ );
+ return Promise.reject(response);
+ }
+
+ return Promise.resolve();
+ };
+
+ handleGetPermissionTemplateUsers = (data: { q?: string | null; p?: number; ps?: number }) => {
+ const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q } = data;
+
+ const users =
+ q && q.length >= MIN_QUERY_LENGTH
+ ? templateUsers.filter((user) =>
+ [user.login, user.name].some((key) => key.toLowerCase().includes(q.toLowerCase()))
+ )
+ : templateUsers;
+
+ const usersChunks = chunk(users, ps);
+
+ return this.reply({
+ paging: { pageSize: ps, total: users.length, pageIndex: p },
+ users: usersChunks[p - 1] ?? [],
+ });
+ };
+
+ handleGetPermissionTemplateGroups = (data: {
+ templateId: string;
+ q?: string | null;
+ permission?: string;
+ p?: number;
+ ps?: number;
+ }) => {
+ const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q } = data;
+
+ const groups =
+ q && q.length >= MIN_QUERY_LENGTH
+ ? templateGroups.filter((group) => group.name.toLowerCase().includes(q.toLowerCase()))
+ : templateGroups;
+
+ const groupsChunks = chunk(groups, ps);
+
+ return this.reply({
+ paging: { pageSize: ps, total: groups.length, pageIndex: p },
+ groups: groupsChunks[p - 1] ?? [],
+ });
+ };
+
+ handleChangeProjectVisibility = (_project: string, _visibility: Visibility) => {
+ return this.reply(undefined);
+ };
+
+ handleGetPermissionGroupsForComponent = (data: {
+ projectKey: string;
+ q?: string;
+ permission?: string;
+ p?: number;
+ ps?: number;
+ }) => {
+ const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q, permission } = data;
+
+ const groups =
+ q && q.length >= MIN_QUERY_LENGTH
+ ? this.groups.filter((group) => group.name.toLowerCase().includes(q.toLowerCase()))
+ : this.groups;
+
+ const groupsChunked = chunk(
+ permission ? groups.filter((g) => g.permissions.includes(permission)) : groups,
+ ps
+ );
+
+ return this.reply({
+ paging: { pageSize: ps, total: groups.length, pageIndex: p },
+ groups: groupsChunked[p - 1] ?? [],
+ });
+ };
+
+ handleGetPermissionUsersForComponent = (data: {
+ projectKey: string;
+ q?: string;
+ permission?: string;
+ p?: number;
+ ps?: number;
+ }) => {
+ const { ps = PAGE_SIZE, p = DEFAULT_PAGE, q, permission } = data;
+
+ const users =
+ q && q.length >= MIN_QUERY_LENGTH
+ ? this.users.filter((user) => user.name.toLowerCase().includes(q.toLowerCase()))
+ : this.users;
+
+ const usersChunked = chunk(
+ permission ? users.filter((u) => u.permissions.includes(permission)) : users,
+ ps
+ );
+
+ return this.reply({
+ paging: { pageSize: ps, total: users.length, pageIndex: p },
+ users: usersChunked[p - 1] ?? [],
+ });
+ };
+
+ handleGrantPermissionToGroup = (data: {
+ projectKey?: string;
+ groupName: string;
+ permission: string;
+ }) => {
+ if (!this.isAllowedPermissionChange) {
+ return Promise.reject();
+ }
+
+ const { groupName, permission } = data;
+ const group = this.groups.find((g) => g.name === groupName);
+ if (group === undefined) {
+ throw new Error(`Could not find group with name ${groupName}`);
+ }
+ group.permissions = uniq([...group.permissions, permission]);
+ return this.reply(undefined);
+ };
+
+ handleRevokePermissionFromGroup = (data: {
+ projectKey?: string;
+ groupName: string;
+ permission: string;
+ }) => {
+ if (!this.isAllowedPermissionChange) {
+ return Promise.reject();
+ }
+
+ const { groupName, permission } = data;
+ const group = this.groups.find((g) => g.name === groupName);
+ if (group === undefined) {
+ throw new Error(`Could not find group with name ${groupName}`);
+ }
+ group.permissions = remove(group.permissions, permission);
+ return this.reply(undefined);
+ };
+
+ handleGrantPermissionToUser = (data: {
+ projectKey?: string;
+ login: string;
+ permission: string;
+ }) => {
+ if (!this.isAllowedPermissionChange) {
+ return Promise.reject();
+ }
+
+ const { login, permission } = data;
+ const user = this.users.find((u) => u.login === login);
+ if (user === undefined) {
+ throw new Error(`Could not find user with login ${login}`);
+ }
+ user.permissions = uniq([...user.permissions, permission]);
+ return this.reply(undefined);
+ };
+
+ handleRevokePermissionFromUser = (data: {
+ projectKey?: string;
+ login: string;
+ permission: string;
+ }) => {
+ if (!this.isAllowedPermissionChange) {
+ return Promise.reject();
+ }
+
+ const { login, permission } = data;
+ const user = this.users.find((u) => u.login === login);
+ if (user === undefined) {
+ throw new Error(`Could not find user with name ${login}`);
+ }
+ user.permissions = remove(user.permissions, permission);
+ return this.reply(undefined);
+ };
+
+ handlePermissionChange = () => {
+ return this.isAllowedPermissionChange ? Promise.resolve() : Promise.reject();
+ };
+
+ updatePermissionChangeAllowance = (val: boolean) => {
+ this.isAllowedPermissionChange = val;
+ };
+
+ setGroups = (groups: PermissionGroup[]) => {
+ this.groups = groups;
+ };
+
+ setUsers = (users: PermissionUser[]) => {
+ this.users = users;
+ };
+
+ reset = () => {
+ this.permissionTemplates = cloneDeep(defaultPermissionTemplates);
+ this.groups = cloneDeep(defaultGroups);
+ this.users = cloneDeep(defaultUsers);
+ this.updatePermissionChangeAllowance(true);
+ };
+
+ reply<T>(response: T): Promise<T> {
+ return Promise.resolve(cloneDeep(response));
+ }
+}
diff --git a/server/sonar-web/src/main/js/api/permissions.ts b/server/sonar-web/src/main/js/api/permissions.ts
index 4247153957f..8e65bd6ead7 100644
--- a/server/sonar-web/src/main/js/api/permissions.ts
+++ b/server/sonar-web/src/main/js/api/permissions.ts
@@ -19,13 +19,13 @@
*/
import { throwGlobalError } from '../helpers/error';
import { getJSON, post, postJSON, RequestData } from '../helpers/request';
+import { Visibility } from '../types/component';
import {
Paging,
Permission,
PermissionGroup,
PermissionTemplate,
PermissionUser,
- Visibility,
} from '../types/types';
import { BaseSearchProjectsParameters } from './components';
@@ -93,7 +93,7 @@ export function setDefaultPermissionTemplate(templateId: string, qualifier: stri
return post('/api/permissions/set_default_template', { templateId, qualifier });
}
-export function applyTemplateToProject(data: RequestData) {
+export function applyTemplateToProject(data: { projectKey: string; templateId: string }) {
return post('/api/permissions/apply_template', data).catch(throwGlobalError);
}