Skip to content

Commit

Permalink
fix(#3372): WIP share adapter test
Browse files Browse the repository at this point in the history
  • Loading branch information
tenthe committed Dec 16, 2024
1 parent e44d670 commit 51ce8c3
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void createDataStreamForAdapter(
var storedDescription = new SourcesManagement()
.createAdapterDataStream(adapterDescription, streamId);
storedDescription.setCorrespondingAdapterId(adapterId);
installDataSource(storedDescription, principalSid, true);
installDataSource(storedDescription, principalSid);
LOG.info("Install source (source URL: {} in backend", adapterDescription.getElementId());
}

Expand Down Expand Up @@ -191,11 +191,10 @@ public void startStreamAdapter(String elementId) throws AdapterException {

private void installDataSource(
SpDataStream stream,
String principalSid,
boolean publicElement
String principalSid
) throws AdapterException {
try {
new DataStreamVerifier(stream).verifyAndAdd(principalSid, publicElement);
new DataStreamVerifier(stream).verifyAndAdd(principalSid, false);
} catch (SepaParseException e) {
LOG.error("Error while installing data source: {}", stream.getElementId(), e);
throw new AdapterException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.streampipes.resource.management.PermissionResourceManager;
import org.apache.streampipes.resource.management.SpResourceManager;
import org.apache.streampipes.rest.security.AuthConstants;
import org.apache.streampipes.rest.security.SpPermissionEvaluator;
import org.apache.streampipes.rest.shared.constants.SpMediaType;
import org.apache.streampipes.storage.api.IPipelineStorage;
import org.apache.streampipes.storage.management.StorageDispatcher;
Expand Down Expand Up @@ -136,7 +137,7 @@ public ResponseEntity<List<PipelineUpdateInfo>> performPipelineMigrationPrefligh
}

@GetMapping(path = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, SpMediaType.YAML, SpMediaType.YML})
@PreAuthorize("this.hasReadAuthority() and hasPermission('#elementId', 'READ')")
@PreAuthorize("this.hasReadAuthority()")
public ResponseEntity<?> getAdapter(
@PathVariable("id") String elementId,
@RequestParam(value = "output",
Expand All @@ -145,7 +146,16 @@ public ResponseEntity<?> getAdapter(
) {

try {
AdapterDescription adapterDescription = getAdapterDescription(elementId);
var adapterDescription = getAdapterDescription(elementId);

// This check is done here because the adapter permission is checked based on the corresponding data stream
// and not based on the element id
if (!checkAdapterReadPermission(adapterDescription)) {
LOG.error("User is not allowed to read adapter {}", elementId);
return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED)
.build();
}

if (outputMode.equalsIgnoreCase("compact")) {
return ok(toCompactAdapterDescription(adapterDescription));
} else {
Expand All @@ -160,6 +170,20 @@ public ResponseEntity<?> getAdapter(
}
}

/**
* Checks if the current user has the permission to read the adapter
*/
private boolean checkAdapterReadPermission(AdapterDescription adapterDescription) {
var spPermissionEvaluator = new SpPermissionEvaluator();
var authentication = SecurityContextHolder.getContext()
.getAuthentication();
return spPermissionEvaluator.hasPermission(
authentication,
adapterDescription.getCorrespondingDataStreamElementId(),
"READ"
);
}

@PostMapping(path = "/{id}/stop", produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("this.hasWriteAuthority() and hasPermission('#elementId', 'WRITE')")
public ResponseEntity<?> stopAdapter(@PathVariable("id") String elementId) {
Expand Down Expand Up @@ -269,7 +293,7 @@ public ResponseEntity<?> deleteAdapter(

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("this.hasReadAuthority()")
@PostFilter("hasPermission(filterObject.elementId, 'READ')")
@PostFilter("hasPermission(filterObject.correspondingDataStreamElementId, 'READ')")
public List<AdapterDescription> getAllAdapters() {
return managementService.getAllAdapterInstances();
}
Expand Down
31 changes: 31 additions & 0 deletions ui/cypress/support/utils/user/PermissionUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { StaticPropertyUtils } from '../userInput/StaticPropertyUtils';

export class PermissionUtils {
public static openManagePermissions() {
cy.dataCy('open-manage-permissions').click();
}

public static markElementAsPublic() {
PermissionUtils.openManagePermissions();
StaticPropertyUtils.clickCheckbox('permission-public-element');
cy.dataCy('sp-manage-permissions-save').click();
}
}
10 changes: 7 additions & 3 deletions ui/cypress/support/utils/userInput/StaticPropertyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class StaticPropertyUtils {
// Configure Properties
configs.forEach(config => {
if (config.type === 'checkbox') {
this.clickCheckbox(config);
this.clickCheckbox(config.selector);
} else if (config.type === 'button') {
cy.dataCy(config.selector, { timeout: 2000 }).click();
} else if (config.type === 'drop-down') {
Expand Down Expand Up @@ -65,8 +65,12 @@ export class StaticPropertyUtils {
});
}

private static clickCheckbox(input: UserInput) {
this.clickSelectionInput(input.selector, '.mdc-checkbox');
/**
* This method can be used to check a mat checkbox
* @param selector
*/
public static clickCheckbox(selector: string) {
this.clickSelectionInput(selector, '.mdc-checkbox');
}

private static clickRadio(input: UserInput) {
Expand Down
43 changes: 43 additions & 0 deletions ui/cypress/tests/connect/enhancedAdapterDeletion.smoke.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
import { UserUtils } from '../../support/utils/UserUtils';
import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';

describe('Test Enhanced Adapter Deletion', () => {
beforeEach('Setup Test', () => {
cy.initStreamPipesTest();
UserUtils.addUser(UserUtils.userWithAdapterAndPipelineAdminRights);
});

it('Test Delete Adapter and Associated Pipelines', () => {
PipelineUtils.addSampleAdapterAndPipeline();

ConnectUtils.deleteAdapterAndAssociatedPipelines();
});

it('Test Admin Should Be Able to Delete Adapter and Not Owned Associated Pipelines', () => {
// Let the user create the adapter and the pipeline
PipelineUtils.addSampleAdapterAndPipeline();

// Then let the admin delete them
UserUtils.switchUser(UserUtils.adminUser);
ConnectUtils.deleteAdapterAndAssociatedPipelines(true);
});
});
43 changes: 0 additions & 43 deletions ui/cypress/tests/connect/multiUser/adapterMultiUserSupport.ts

This file was deleted.

This file was deleted.

72 changes: 51 additions & 21 deletions ui/cypress/tests/userManagement/testUserRoleConnect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,70 @@
* limitations under the License.
*
*/
import { UserBuilder } from '../../support/builder/UserBuilder';
import { UserRole } from '../../../src/app/_enums/user-role.enum';
import { UserUtils } from '../../support/utils/UserUtils';
import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
import { ConnectBtns } from '../../support/utils/connect/ConnectBtns';
import { GeneralUtils } from '../../support/utils/GeneralUtils';
import { PermissionUtils } from '../../support/utils/user/PermissionUtils';

describe('Test User Roles for Connect', () => {
beforeEach('Setup Test', () => {
cy.initStreamPipesTest();
ConnectUtils.addMachineDataSimulator('simulator');
});

it('Perform Test', () => {
// Add connect admin user
const connect_admin = UserBuilder.create('[email protected]')
.setName('connect_admin')
.setPassword('password')
.addRole(UserRole.ROLE_CONNECT_ADMIN)
.build();
UserUtils.addUser(connect_admin);
// it('Connect admin should not see adapters of other users', () => {
// const connectAdminUser = UserUtils.createUser(
// 'user',
// UserRole.ROLE_CONNECT_ADMIN,
// );
//
// ConnectUtils.addMachineDataSimulator('simulator');
//
// UserUtils.switchUser(connectAdminUser);
//
// GeneralUtils.validateAmountOfNavigationIcons(3);
//
// // Validate that no adapter is visible
// ConnectUtils.checkAmountOfAdapters(0);
// });

// it('Connect admin should see public adapters of other users', () => {
// const connectAdminUser = UserUtils.createUser(
// 'user',
// UserRole.ROLE_CONNECT_ADMIN,
// );
//
// ConnectUtils.addMachineDataSimulator('simulator');
//
// // Set adapter to public
// PermissionUtils.markElementAsPublic();
//
// UserUtils.switchUser(connectAdminUser);
//
// GeneralUtils.validateAmountOfNavigationIcons(3);
//
// // Validate that adapter is visible
// ConnectUtils.checkAmountOfAdapters(1);
// });

// Login as user and check if connect is visible to user
UserUtils.switchUser(connect_admin);
it('Connect admin should see shared adapters of other users', () => {
const connectAdminUser = UserUtils.createUser(
'user',
UserRole.ROLE_CONNECT_ADMIN,
);

GeneralUtils.validateAmountOfNavigationIcons(3);
ConnectUtils.addMachineDataSimulator('simulator');

ConnectUtils.goToConnect();
// Set adapter to public
PermissionUtils.openManagePermissions();
cy.dataCy('authorized-user').type(`${connectAdminUser.email}{tab}`);

ConnectUtils.checkAmountOfAdapters(1);
// cy.dataCy('sp-manage-permissions-save').click();

// validate that adapter can be stopped and edited
ConnectBtns.stopAdapter().click();
ConnectBtns.editAdapter().should('not.be.disabled');
ConnectBtns.editAdapter().click();
// UserUtils.switchUser(connectAdminUser);
//
// GeneralUtils.validateAmountOfNavigationIcons(3);
//
// // Validate that adapter is visible
// ConnectUtils.checkAmountOfAdapters(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ <h5>
mat-icon-button
matTooltip="Manage permissions"
matTooltipPosition="above"
data-cy="open-manage-permissions"
*ngIf="isAdmin"
(click)="showPermissionsDialog(adapter)"
>
Expand Down
Loading

0 comments on commit 51ce8c3

Please sign in to comment.