Skip to content

Commit

Permalink
Merge pull request DSpace#3693 from alexandrevryghem/w2p-121534_remov…
Browse files Browse the repository at this point in the history
…ed-metadata-export-search-request-for-non-admins-on-search_contribute-main

Removed unauthorized metadata-export-search request on search page
  • Loading branch information
tdonohue authored Dec 3, 2024
2 parents 3ca56c3 + 0b3cb79 commit 37bd26e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { AuthorizationDataService } from '../../../core/data/feature-authorizati
import { ScriptDataService } from '../../../core/data/processes/script-data.service';
import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths';
import { Process } from '../../../process-page/processes/process.model';
import { Script } from '../../../process-page/scripts/script.model';
import { NotificationsService } from '../../notifications/notifications.service';
import {
createFailedRemoteDataObject$,
Expand All @@ -33,7 +32,6 @@ describe('SearchExportCsvComponent', () => {
let notificationsService;
let router;

const script = Object.assign(new Script(), { id: 'metadata-export-search', name: 'metadata-export-search' });
const process = Object.assign(new Process(), { processId: 5, scriptName: 'metadata-export-search' });

const searchConfig = new PaginatedSearchOptions({
Expand All @@ -49,7 +47,7 @@ describe('SearchExportCsvComponent', () => {

function initBeforeEachAsync() {
scriptDataService = jasmine.createSpyObj('scriptDataService', {
findById: createSuccessfulRemoteDataObject$(script),
scriptWithNameExistsAndCanExecute: observableOf(true),
invoke: createSuccessfulRemoteDataObject$(process),
});
authorizationDataService = jasmine.createSpyObj('authorizationService', {
Expand Down Expand Up @@ -117,15 +115,22 @@ describe('SearchExportCsvComponent', () => {
describe('when the metadata-export-search script is not present', () => {
beforeEach(waitForAsync(() => {
initBeforeEachAsync();
(scriptDataService.findById as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Not found', 404));
(scriptDataService.scriptWithNameExistsAndCanExecute as jasmine.Spy).and.returnValue(observableOf(false));
}));
beforeEach(() => {
initBeforeEach();
});

it('should should not add the button', () => {
initBeforeEach();

const debugElement = fixture.debugElement.query(By.css('button.export-button'));
expect(debugElement).toBeNull();
});

it('should not call scriptWithNameExistsAndCanExecute when unauthorized', () => {
(authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false));
initBeforeEach();

expect(scriptDataService.scriptWithNameExistsAndCanExecute).not.toHaveBeenCalled();
});
});
});
describe('export', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import {
TranslateModule,
TranslateService,
} from '@ngx-translate/core';
import { Observable } from 'rxjs';
import {
combineLatest as observableCombineLatest,
Observable,
} from 'rxjs';
import { map } from 'rxjs/operators';
filter,
map,
startWith,
switchMap,
} from 'rxjs/operators';

import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
Expand All @@ -32,6 +34,7 @@ import {
} from '../../empty.util';
import { NotificationsService } from '../../notifications/notifications.service';
import { PaginatedSearchOptions } from '../models/paginated-search-options.model';
import { SearchFilter } from '../models/search-filter.model';

@Component({
selector: 'ds-search-export-csv',
Expand Down Expand Up @@ -69,15 +72,11 @@ export class SearchExportCsvComponent implements OnInit {
}

ngOnInit(): void {
const scriptExists$ = this.scriptDataService.findById('metadata-export-search').pipe(
getFirstCompletedRemoteData(),
map((rd) => rd.isSuccess && hasValue(rd.payload)),
);

const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf);

this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe(
map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized),
this.shouldShowButton$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf).pipe(
filter((isAuthorized: boolean) => isAuthorized),
switchMap(() => this.scriptDataService.scriptWithNameExistsAndCanExecute('metadata-export-search')),
map((canExecute: boolean) => canExecute),
startWith(false),
);
}

Expand All @@ -97,19 +96,19 @@ export class SearchExportCsvComponent implements OnInit {
parameters.push({ name: '-c', value: this.searchConfig.configuration });
}
if (isNotEmpty(this.searchConfig.filters)) {
this.searchConfig.filters.forEach((filter) => {
if (hasValue(filter.values)) {
filter.values.forEach((value) => {
this.searchConfig.filters.forEach((searchFilter: SearchFilter) => {
if (hasValue(searchFilter.values)) {
searchFilter.values.forEach((value: string) => {
let operator;
let filterValue;
if (hasValue(filter.operator)) {
operator = filter.operator;
if (hasValue(searchFilter.operator)) {
operator = searchFilter.operator;
filterValue = value;
} else {
operator = value.substring(value.lastIndexOf(',') + 1);
filterValue = value.substring(0, value.lastIndexOf(','));
}
const valueToAdd = `${filter.key.substring(2)},${operator}=${filterValue}`;
const valueToAdd = `${searchFilter.key.substring(2)},${operator}=${filterValue}`;
parameters.push({ name: '-f', value: valueToAdd });
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class SearchFacetFilterComponent implements OnInit, OnDestroy {
this.currentUrl = this.router.url;
this.currentPage = this.getCurrentPage().pipe(distinctUntilChanged());
this.searchOptions$ = this.searchConfigService.searchOptions.pipe(
map((options: SearchOptions) => hasNoValue(this.scope) ? options : Object.assign({}, options, {
map((options: SearchOptions) => hasNoValue(this.scope) ? options : Object.assign(new SearchOptions(options), {
scope: this.scope,
})),
);
Expand Down

0 comments on commit 37bd26e

Please sign in to comment.