mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
94273: Make isAuthorized depend on the target object
This ensures that a successful ItemDataService.setWithdrawn call invalidates all related authorizations
This commit is contained in:
@@ -3,7 +3,7 @@ import { SiteDataService } from '../site-data.service';
|
||||
import { AuthService } from '../../auth/auth.service';
|
||||
import { Site } from '../../shared/site.model';
|
||||
import { EPerson } from '../../eperson/models/eperson.model';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { of as observableOf, combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
||||
import { FeatureID } from './feature-id';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { RequestParam } from '../../cache/models/request-param.model';
|
||||
@@ -17,6 +17,7 @@ describe('AuthorizationDataService', () => {
|
||||
let service: AuthorizationDataService;
|
||||
let siteService: SiteDataService;
|
||||
let authService: AuthService;
|
||||
let objectCache;
|
||||
|
||||
let site: Site;
|
||||
let ePerson: EPerson;
|
||||
@@ -43,7 +44,11 @@ describe('AuthorizationDataService', () => {
|
||||
isAuthenticated: () => observableOf(true),
|
||||
getAuthenticatedUserFromStore: () => observableOf(ePerson)
|
||||
} as AuthService;
|
||||
service = new AuthorizationDataService(requestService, undefined, undefined, undefined, undefined, undefined, undefined, undefined, authService, siteService);
|
||||
objectCache = jasmine.createSpyObj('objectCache', {
|
||||
addDependency: undefined,
|
||||
removeDependents: undefined,
|
||||
});
|
||||
service = new AuthorizationDataService(requestService, undefined, undefined, objectCache, undefined, undefined, undefined, undefined, authService, siteService);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -110,6 +115,43 @@ describe('AuthorizationDataService', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(objectUrl, ePersonUuid, FeatureID.LoginOnBehalfOf), true, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dependencies', () => {
|
||||
let addDependencySpy;
|
||||
|
||||
beforeEach(() => {
|
||||
(service.searchBy as any).and.returnValue(observableOf('searchBy RD$'));
|
||||
addDependencySpy = spyOn(service as any, 'addDependency');
|
||||
});
|
||||
|
||||
it('should add a dependency on the objectUrl', (done) => {
|
||||
addDependencySpy.and.callFake((href$: Observable<string>, dependsOn$: Observable<string>) => {
|
||||
observableCombineLatest([href$, dependsOn$]).subscribe(([href, dependsOn]) => {
|
||||
expect(href).toBe('searchBy RD$');
|
||||
expect(dependsOn).toBe('object-href');
|
||||
});
|
||||
});
|
||||
|
||||
service.searchByObject(FeatureID.AdministratorOf, 'object-href').subscribe(() => {
|
||||
expect(addDependencySpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a dependency on the Site object if no objectUrl is given', (done) => {
|
||||
addDependencySpy.and.callFake((object$: Observable<any>, dependsOn$: Observable<string>) => {
|
||||
observableCombineLatest([object$, dependsOn$]).subscribe(([object, dependsOn]) => {
|
||||
expect(object).toBe('searchBy RD$');
|
||||
expect(dependsOn).toBe('test-site-href');
|
||||
});
|
||||
});
|
||||
|
||||
service.searchByObject(FeatureID.AdministratorOf).subscribe(() => {
|
||||
expect(addDependencySpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAuthorized', () => {
|
||||
|
@@ -18,10 +18,10 @@ import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-
|
||||
import { RemoteData } from '../remote-data';
|
||||
import { PaginatedList } from '../paginated-list.model';
|
||||
import { catchError, map, switchMap } from 'rxjs/operators';
|
||||
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { hasNoValue, hasValue, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { RequestParam } from '../../cache/models/request-param.model';
|
||||
import { AuthorizationSearchParams } from './authorization-search-params';
|
||||
import { addSiteObjectUrlIfEmpty, oneAuthorizationMatchesFeature } from './authorization-utils';
|
||||
import { oneAuthorizationMatchesFeature } from './authorization-utils';
|
||||
import { FeatureID } from './feature-id';
|
||||
import { getFirstCompletedRemoteData } from '../../shared/operators';
|
||||
import { CoreState } from '../../core-state.model';
|
||||
@@ -102,12 +102,28 @@ export class AuthorizationDataService extends DataService<Authorization> {
|
||||
* {@link HALLink}s should be automatically resolved
|
||||
*/
|
||||
searchByObject(featureId?: FeatureID, objectUrl?: string, ePersonUuid?: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<Authorization>[]): Observable<RemoteData<PaginatedList<Authorization>>> {
|
||||
return observableOf(new AuthorizationSearchParams(objectUrl, ePersonUuid, featureId)).pipe(
|
||||
addSiteObjectUrlIfEmpty(this.siteService),
|
||||
const objectUrl$ = observableOf(objectUrl).pipe(
|
||||
switchMap((url) => {
|
||||
if (hasNoValue(url)) {
|
||||
return this.siteService.find().pipe(
|
||||
map((site) => site.self)
|
||||
);
|
||||
} else {
|
||||
return observableOf(url);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const out$ = objectUrl$.pipe(
|
||||
map((url: string) => new AuthorizationSearchParams(url, ePersonUuid, featureId)),
|
||||
switchMap((params: AuthorizationSearchParams) => {
|
||||
return this.searchBy(this.searchByObjectPath, this.createSearchOptions(params.objectUrl, options, params.ePersonUuid, params.featureId), useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
|
||||
})
|
||||
);
|
||||
|
||||
this.addDependency(out$, objectUrl$);
|
||||
|
||||
return out$;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user