Skip to content

Commit ffe69ba

Browse files
author
Andrea Barbasso
committed
Merged dspace-cris-2023_02_x into task/dspace-cris-2023_02_x/DSC-1821
2 parents 847704d + 965034b commit ffe69ba

18 files changed

Lines changed: 175 additions & 59 deletions

File tree

src/app/admin/admin-routing.module.ts

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ import { AdminEditUserAgreementComponent } from './admin-edit-user-agreement/adm
1010
import { NOTIFICATIONS_MODULE_PATH, REGISTRIES_MODULE_PATH } from './admin-routing-paths';
1111
import { EditCmsMetadataComponent } from './edit-cms-metadata/edit-cms-metadata.component';
1212
import { BatchImportPageComponent } from './admin-import-batch-page/batch-import-page.component';
13+
import {
14+
SiteAdministratorGuard
15+
} from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
16+
import {
17+
GenericAdministratorGuard
18+
} from '../core/data/feature-authorization/feature-authorization-guard/generic-administrator-guard';
1319

1420
@NgModule({
1521
imports: [
@@ -18,59 +24,69 @@ import { BatchImportPageComponent } from './admin-import-batch-page/batch-import
1824
path: NOTIFICATIONS_MODULE_PATH,
1925
loadChildren: () => import('./admin-notifications/admin-notifications.module')
2026
.then((m) => m.AdminNotificationsModule),
27+
canActivate: [SiteAdministratorGuard]
2128
},
2229
{
2330
path: REGISTRIES_MODULE_PATH,
2431
loadChildren: () => import('./admin-registries/admin-registries.module')
2532
.then((m) => m.AdminRegistriesModule),
33+
canActivate: [SiteAdministratorGuard]
2634
},
2735
{
2836
path: 'search',
2937
resolve: { breadcrumb: I18nBreadcrumbResolver },
3038
component: AdminSearchPageComponent,
31-
data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' }
39+
data: { title: 'admin.search.title', breadcrumbKey: 'admin.search' },
40+
canActivate: [GenericAdministratorGuard]
3241
},
3342
{
3443
path: 'workflow',
3544
resolve: { breadcrumb: I18nBreadcrumbResolver },
3645
component: AdminWorkflowPageComponent,
37-
data: { title: 'admin.workflow.title', breadcrumbKey: 'admin.workflow' }
46+
data: { title: 'admin.workflow.title', breadcrumbKey: 'admin.workflow' },
47+
canActivate: [SiteAdministratorGuard]
3848
},
3949
{
4050
path: 'curation-tasks',
4151
resolve: { breadcrumb: I18nBreadcrumbResolver },
4252
component: AdminCurationTasksComponent,
43-
data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' }
53+
data: { title: 'admin.curation-tasks.title', breadcrumbKey: 'admin.curation-tasks' },
54+
canActivate: [SiteAdministratorGuard]
4455
},
4556
{
4657
path: 'metadata-import',
4758
resolve: { breadcrumb: I18nBreadcrumbResolver },
4859
component: MetadataImportPageComponent,
49-
data: { title: 'admin.metadata-import.title', breadcrumbKey: 'admin.metadata-import' }
60+
data: { title: 'admin.metadata-import.title', breadcrumbKey: 'admin.metadata-import' },
61+
canActivate: [GenericAdministratorGuard]
5062
},
5163
{
5264
path: 'edit-user-agreement',
5365
resolve: { breadcrumb: I18nBreadcrumbResolver },
5466
component: AdminEditUserAgreementComponent,
55-
data: { title: 'admin.edit-user-agreement.title', breadcrumbKey: 'admin.edit-user-agreement' }
67+
data: { title: 'admin.edit-user-agreement.title', breadcrumbKey: 'admin.edit-user-agreement' },
68+
canActivate: [SiteAdministratorGuard]
5669
},
5770
{
5871
path: 'edit-cms-metadata',
5972
resolve: { breadcrumb: I18nBreadcrumbResolver },
6073
component: EditCmsMetadataComponent,
61-
data: { title: 'admin.edit-cms-metadata.title', breadcrumbKey: 'admin.edit-cms-metadata' }
74+
data: { title: 'admin.edit-cms-metadata.title', breadcrumbKey: 'admin.edit-cms-metadata' },
75+
canActivate: [SiteAdministratorGuard]
6276
},
6377
{
6478
path: 'batch-import',
6579
resolve: { breadcrumb: I18nBreadcrumbResolver },
6680
component: BatchImportPageComponent,
67-
data: { title: 'admin.batch-import.title', breadcrumbKey: 'admin.batch-import' }
81+
data: { title: 'admin.batch-import.title', breadcrumbKey: 'admin.batch-import' },
82+
canActivate: [GenericAdministratorGuard]
6883
},
6984
{
7085
path: 'system-wide-alert',
7186
resolve: { breadcrumb: I18nBreadcrumbResolver },
7287
loadChildren: () => import('../system-wide-alert/system-wide-alert.module').then((m) => m.SystemWideAlertModule),
73-
data: {title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert'}
88+
data: {title: 'admin.system-wide-alert.title', breadcrumbKey: 'admin.system-wide-alert'},
89+
canActivate: [SiteAdministratorGuard]
7490
},
7591
])
7692
],

src/app/admin/edit-cms-metadata/edit-cms-metadata.component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export class EditCmsMetadataComponent implements OnInit {
8383
this.notificationsService.error(this.translateService.get('admin.edit-cms-metadata.error'));
8484
}
8585
this.siteService.setStale();
86+
this.siteService.find().subscribe((site) => {
87+
this.site = site;
88+
});
8689
});
8790
}
8891

src/app/app-routing.module.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import { NoPreloading, RouterModule } from '@angular/router';
33
import { AuthBlockingGuard } from './core/auth/auth-blocking.guard';
44

55
import { AuthenticatedGuard } from './core/auth/authenticated.guard';
6-
import {
7-
SiteAdministratorGuard
8-
} from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard';
6+
7+
98
import {
109
ACCESS_CONTROL_MODULE_PATH,
1110
ADMIN_MODULE_PATH,
@@ -46,6 +45,11 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone
4645
import { ForgotPasswordCheckGuard } from './core/rest-property/forgot-password-check-guard.guard';
4746
import { SUGGESTION_MODULE_PATH } from './suggestions-page/suggestions-page-routing-paths';
4847
import { RedirectService } from './redirect/redirect.service';
48+
import {
49+
GenericAdministratorGuard
50+
} from './core/data/feature-authorization/feature-authorization-guard/generic-administrator-guard';
51+
52+
4953

5054
@NgModule({
5155
imports: [
@@ -168,7 +172,7 @@ import { RedirectService } from './redirect/redirect.service';
168172
path: ADMIN_MODULE_PATH,
169173
loadChildren: () => import('./admin/admin.module')
170174
.then((m) => m.AdminModule),
171-
canActivate: [SiteAdministratorGuard, EndUserAgreementCurrentUserGuard]
175+
canActivate: [GenericAdministratorGuard, EndUserAgreementCurrentUserGuard]
172176
},
173177
{
174178
path: 'login',
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Injectable } from '@angular/core';
2+
import { FeatureID } from '../feature-id';
3+
import { AuthorizationDataService } from '../authorization-data.service';
4+
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
5+
import { Observable, of as observableOf } from 'rxjs';
6+
import { AuthService } from '../../../auth/auth.service';
7+
import { SomeFeatureAuthorizationGuard } from './some-feature-authorization.guard';
8+
9+
/**
10+
* Prevent unauthorized activating and loading of routes when the current authenticated user doesn't have administrator
11+
* rights to the {@link Site}, Community or Collection
12+
*/
13+
@Injectable({
14+
providedIn: 'root'
15+
})
16+
export class GenericAdministratorGuard extends SomeFeatureAuthorizationGuard {
17+
constructor(protected authorizationService: AuthorizationDataService, protected router: Router, protected authService: AuthService) {
18+
super(authorizationService, router, authService);
19+
}
20+
21+
/**
22+
* Check if user have administrator rights to Site, Community or Collection
23+
*/
24+
getFeatureIDs(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<FeatureID[]> {
25+
return observableOf([
26+
FeatureID.AdministratorOf,
27+
FeatureID.IsCommunityAdmin,
28+
FeatureID.IsCollectionAdmin,
29+
]);
30+
}
31+
}

src/app/core/shared/client-math.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class ClientMathService extends MathService {
2222

2323
protected mathJaxOptions = {
2424
tex: {
25-
inlineMath: [['$', '$'], ['\\(', '\\)']]
25+
inlineMath: [['$', '$'], ['$$', '$$'], ['\\(', '\\)']]
2626
},
2727
svg: {
2828
fontCache: 'global'
@@ -99,7 +99,7 @@ export class ClientMathService extends MathService {
9999
*/
100100
render(element: HTMLElement) {
101101
if (environment.markdown.mathjax) {
102-
this._window.nativeWindow.MathJax.typesetPromise([element]);
102+
return (window as any).MathJax.typesetPromise([element]) as Promise<any>;
103103
}
104104
}
105105
}

src/app/core/shared/math.service.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export class MockMathService extends MathService {
1515
return of(true);
1616
}
1717

18-
render(element: HTMLElement): void {
19-
return;
18+
render(element: HTMLElement): Promise<any> {
19+
return Promise.resolve();
2020
}
2121
}
2222

src/app/core/shared/math.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ export abstract class MathService {
1515

1616
protected abstract registerMathJaxAsync(config: MathJaxConfig): Promise<any>;
1717
abstract ready(): Observable<boolean>;
18-
abstract render(element: HTMLElement): void;
18+
abstract render(element: HTMLElement): Promise<any>;
1919
}

src/app/core/shared/server-math.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ export class ServerMathService extends MathService {
3939
}
4040

4141
render(element: HTMLElement) {
42-
return;
42+
return Promise.resolve();
4343
}
4444
}

src/app/item-page/simple/item-page.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div
33
[ngClass]="{'container': (itemRD?.hasSucceeded && !itemRD?.hasNoContent) && tabsRD?.payload?.pageInfo?.totalElements < 1}"
44
*ngVar="(itemRD$ | async) as itemRD">
5-
<div class="py-1" [ngClass]="{'container': (itemRD?.hasSucceeded && !itemRD?.hasNoContent) && tabsRD?.payload?.pageInfo?.totalElements > 0}">
5+
<div [ngClass]="{'container': (itemRD?.hasSucceeded && !itemRD?.hasNoContent) && tabsRD?.payload?.pageInfo?.totalElements > 0}">
66
<ds-item-versions-notice [item]="itemRD?.payload" ></ds-item-versions-notice>
77
</div>
88
<div class="item-page" *ngIf="(itemRD?.hasSucceeded && !itemRD?.hasNoContent) && tabsRD?.payload?.pageInfo?.totalElements < 1" @fadeInOut>

src/app/menu.resolver.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from '@angular/core';
22
import { ActivatedRoute, ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
3-
import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
3+
import { combineLatest, combineLatest as observableCombineLatest, Observable } from 'rxjs';
44
import { MenuID } from './shared/menu/menu-id.model';
55
import { MenuState } from './shared/menu/menu-state.model';
66
import { MenuItemType } from './shared/menu/menu-item-type.model';
@@ -318,7 +318,7 @@ export class MenuResolver implements Resolve<boolean> {
318318
id: 'new_item',
319319
parentID: 'new',
320320
active: false,
321-
visible: isSiteAdmin,
321+
visible: isSiteAdmin || isCommunityAdmin || isCollectionAdmin,
322322
model: {
323323
type: MenuItemType.ONCLICK,
324324
text: 'menu.section.new_item',
@@ -451,7 +451,19 @@ export class MenuResolver implements Resolve<boolean> {
451451
// icon: 'cogs',
452452
// index: 9
453453
// },
454-
454+
/* Admin Search */
455+
{
456+
id: 'admin_search',
457+
active: false,
458+
visible: isSiteAdmin || isCollectionAdmin || isCommunityAdmin,
459+
model: {
460+
type: MenuItemType.LINK,
461+
text: 'menu.section.admin_search',
462+
link: '/admin/search'
463+
} as LinkMenuItemModel,
464+
index: 5,
465+
icon: 'search',
466+
},
455467
/* Processes */
456468
{
457469
id: 'processes',
@@ -532,8 +544,14 @@ export class MenuResolver implements Resolve<boolean> {
532544
];
533545
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, menuSection));
534546

535-
this.authorizationService.isAuthorized(FeatureID.AdministratorOf).pipe(
536-
filter((authorized: boolean) => authorized),
547+
combineLatest([
548+
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
549+
this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin),
550+
this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin),
551+
]).pipe(
552+
filter(([isAdmin, isCommunityAdmin, isCollectionAdmin]) =>
553+
isAdmin || isCollectionAdmin || isCommunityAdmin
554+
),
537555
take(1),
538556
switchMap(() => this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME)),
539557
filter((metadataExportScriptExists: boolean) => metadataExportScriptExists),
@@ -659,8 +677,14 @@ export class MenuResolver implements Resolve<boolean> {
659677
const menuList = [];
660678
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, menuSection));
661679

662-
this.authorizationService.isAuthorized(FeatureID.AdministratorOf).pipe(
663-
filter((authorized: boolean) => authorized),
680+
combineLatest([
681+
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
682+
this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin),
683+
this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin),
684+
]).pipe(
685+
filter(([isAdmin, isCommunityAdmin, isCollectionAdmin]) =>
686+
isAdmin || isCollectionAdmin || isCommunityAdmin
687+
),
664688
take(1),
665689
switchMap(() => this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME)),
666690
filter((metadataImportScriptExists: boolean) => metadataImportScriptExists),
@@ -761,19 +785,6 @@ export class MenuResolver implements Resolve<boolean> {
761785
link: '/admin/notifications/' + NOTIFICATIONS_RECITER_SUGGESTION_PATH
762786
} as LinkMenuItemModel,
763787
},
764-
/* Admin Search */
765-
{
766-
id: 'admin_search',
767-
active: false,
768-
visible: authorized,
769-
model: {
770-
type: MenuItemType.LINK,
771-
text: 'menu.section.admin_search',
772-
link: '/admin/search'
773-
} as LinkMenuItemModel,
774-
icon: 'search',
775-
index: 5
776-
},
777788
/* Registries */
778789
{
779790
id: 'registries',

0 commit comments

Comments
 (0)