diff --git a/demo-shell/src/app/components/app-layout/user-info/user-info.component.ts b/demo-shell/src/app/components/app-layout/user-info/user-info.component.ts new file mode 100644 index 0000000000..6024062112 --- /dev/null +++ b/demo-shell/src/app/components/app-layout/user-info/user-info.component.ts @@ -0,0 +1,112 @@ +/*! + * @license + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed 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 { EcmUserModel, PeopleContentService } from '@alfresco/adf-content-services'; +import { PeopleProcessService } from '@alfresco/adf-process-services'; +import { AuthenticationService, BasicAlfrescoAuthService, IdentityUserModel, IdentityUserService, UserInfoMode } from '@alfresco/adf-core'; +import { Component, OnInit, Input } from '@angular/core'; +import { MenuPositionX, MenuPositionY } from '@angular/material/menu'; +import { Observable, of } from 'rxjs'; +import { UserRepresentation } from '@alfresco/js-api'; + +@Component({ + selector: 'app-shell-user-info', + templateUrl: './user-info.component.html' +}) +export class UserInfoComponent implements OnInit { + /** Custom choice for opening the menu at the bottom. Can be `before` or `after`. */ + @Input() + menuPositionX: MenuPositionX = 'after'; + + /** Custom choice for opening the menu at the bottom. Can be `above` or `below`. */ + @Input() + menuPositionY: MenuPositionY = 'below'; + + mode: UserInfoMode; + ecmUser$: Observable; + bpmUser$: Observable; + identityUser$: Observable; + userInfoMode = UserInfoMode; + + constructor( + private peopleContentService: PeopleContentService, + private peopleProcessService: PeopleProcessService, + private identityUserService: IdentityUserService, + private basicAlfrescoAuthService: BasicAlfrescoAuthService, + private authService: AuthenticationService + ) {} + + ngOnInit() { + this.getUserInfo(); + } + + getUserInfo() { + if (this.authService.isOauth()) { + this.loadIdentityUserInfo(); + this.mode = UserInfoMode.SSO; + + if (this.authService.isECMProvider() && this.authService.isLoggedIn()) { + this.mode = UserInfoMode.CONTENT_SSO; + this.loadEcmUserInfo(); + } + } else if (this.isAllLoggedIn()) { + this.loadEcmUserInfo(); + this.loadBpmUserInfo(); + this.mode = UserInfoMode.ALL; + } else if (this.isEcmLoggedIn()) { + this.loadEcmUserInfo(); + this.mode = UserInfoMode.CONTENT; + } else if (this.isBpmLoggedIn()) { + this.loadBpmUserInfo(); + this.mode = UserInfoMode.PROCESS; + } + } + + get isLoggedIn(): boolean { + if (this.basicAlfrescoAuthService.isKerberosEnabled()) { + return true; + } + return this.authService.isLoggedIn(); + } + + private loadEcmUserInfo(): void { + this.ecmUser$ = this.peopleContentService.getCurrentUserInfo(); + } + + private loadBpmUserInfo() { + this.bpmUser$ = this.peopleProcessService.getCurrentUserInfo(); + } + + private loadIdentityUserInfo() { + this.identityUser$ = of(this.identityUserService.getCurrentUserInfo()); + } + + private isAllLoggedIn() { + return ( + (this.authService.isEcmLoggedIn() && this.authService.isBpmLoggedIn()) || + (this.authService.isALLProvider() && this.basicAlfrescoAuthService.isKerberosEnabled()) + ); + } + + private isBpmLoggedIn() { + return this.authService.isBpmLoggedIn() || (this.authService.isECMProvider() && this.basicAlfrescoAuthService.isKerberosEnabled()); + } + + private isEcmLoggedIn() { + return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.basicAlfrescoAuthService.isKerberosEnabled()); + } +} diff --git a/docs/core/services/authentication.service.md b/docs/core/services/authentication.service.md index c460dc8a06..1cf92cca9d 100644 --- a/docs/core/services/authentication.service.md +++ b/docs/core/services/authentication.service.md @@ -5,7 +5,7 @@ Status: Active Last reviewed: 2019-03-19 --- -# [Authentication Service](../../../lib/core/src/lib/auth/services/authentication.service.ts "Defined in authentication.service.ts") +# Authentication Service Provides authentication to ACS and APS. @@ -19,15 +19,6 @@ Provides authentication to ACS and APS. - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - The new header with the token added - **getBearerExcludedUrls**()
Gets the set of URLs that the token bearer is excluded from. -- **getBpmLoggedUser**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserRepresentation.md)`>`
- Gets information about the user currently logged into APS. - - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserRepresentation.md)`>` - User information -- **getBpmUsername**(): `string`
- Gets the BPM username - - **Returns** `string` - The BPM username -- **getEcmUsername**(): `string`
- Gets the ECM username. - - **Returns** `string` - The ECM username - **getRedirect**(): `string`
Gets the URL to redirect to after login. - **Returns** `string` - The redirect URL @@ -43,43 +34,26 @@ Provides authentication to ACS and APS. - **getToken**(): `string`
Gets the auth token. - **Returns** `string` - Auth token string -- **handleError**(error: `any`): [`Observable`](http://reactivex.io/documentation/observable.html)``
- Prints an error message in the console browser - - _error:_ `any` - Error message - - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Object representing the error message - **isALLProvider**(): `boolean`
Does the provider support both ECM and BPM? - **Returns** `boolean` - True if both are supported, false otherwise - **isBPMProvider**(): `boolean`
Does the provider support BPM? - **Returns** `boolean` - True if supported, false otherwise -- **isBpmLoggedIn**(): `boolean`
- Checks if the user is logged in on a BPM provider. - - **Returns** `boolean` - True if logged in, false otherwise - **isECMProvider**(): `boolean`
Does the provider support ECM? - **Returns** `boolean` - True if supported, false otherwise -- **isEcmLoggedIn**(): `boolean`
- Checks if the user is logged in on an ECM provider. - - **Returns** `boolean` - True if logged in, false otherwise - **isKerberosEnabled**(): `boolean`
Does kerberos enabled? - **Returns** `boolean` - True if enabled, false otherwise - **isLoggedIn**(): `boolean`
Checks if the user logged in. - **Returns** `boolean` - True if logged in, false otherwise -- **isLoggedInWith**(provider: `string`): `boolean`
- - - _provider:_ `string` - - - **Returns** `boolean` - - - **isOauth**(): `boolean`
Does the provider support OAuth? - **Returns** `boolean` - True if supported, false otherwise - **isPublicUrl**(): `boolean`
- - - **Returns** `boolean` - - + - **Returns** `boolean` - - **isRememberMeSet**(): `boolean`
Checks whether the "remember me" cookie was set or not. - **Returns** `boolean` - True if set, false otherwise @@ -89,11 +63,9 @@ Provides authentication to ACS and APS. - _password:_ `string` - Password for the login - _rememberMe:_ `boolean` - Stores the user's login details if true - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Object with auth type ("ECM", "BPM" or "ALL") and auth ticket -- **logout**(): [`Observable`](http://reactivex.io/documentation/observable.html)``
- Logs the user out. +- **logout**(): [`Observable`](http://reactivex.io/documentation/observable.html)``
Logs the user out. - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`` - Response event called when logout is complete - **reset**()
- - **saveRememberMeCookie**(rememberMe: `boolean`)
Saves the "remember me" cookie as either a long-life cookie or a session cookie. - _rememberMe:_ `boolean` - Enables a long-life cookie diff --git a/lib/content-services/src/lib/common/services/content.service.spec.ts b/lib/content-services/src/lib/common/services/content.service.spec.ts index 23d4de790d..295bb7a24a 100644 --- a/lib/content-services/src/lib/common/services/content.service.spec.ts +++ b/lib/content-services/src/lib/common/services/content.service.spec.ts @@ -156,7 +156,7 @@ describe('ContentService', () => { }); it('should take current logged user id if userId undefined ', () => { - spyOn(authService, 'getEcmUsername').and.returnValue('user1'); + spyOn(authService, 'getUsername').and.returnValue('user1'); const permissionNode = new Node({ permissions: { inherited: [ diff --git a/lib/content-services/src/lib/common/services/content.service.ts b/lib/content-services/src/lib/common/services/content.service.ts index dc1c2bfe1f..a6f4ae2065 100644 --- a/lib/content-services/src/lib/common/services/content.service.ts +++ b/lib/content-services/src/lib/common/services/content.service.ts @@ -84,7 +84,7 @@ export class ContentService { */ hasPermissions(node: Node, permission: PermissionsEnum | string, userId?: string): boolean { let hasPermissions = false; - userId = userId ?? this.authService.getEcmUsername(); + userId = userId ?? this.authService.getUsername(); const permissions = [...(node.permissions?.locallySet || []), ...(node.permissions?.inherited || [])].filter( (currentPermission) => currentPermission.authorityId === userId diff --git a/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.spec.ts b/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.spec.ts index 2567033de2..4a792b20d6 100644 --- a/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.spec.ts +++ b/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.spec.ts @@ -274,7 +274,7 @@ describe('DropdownSitesComponent', () => { }); it('should show only sites which logged user is member of when member relation is set', async () => { - spyOn(authService, 'getEcmUsername').and.returnValue('test'); + spyOn(authService, 'getUsername').and.returnValue('test'); fixture.detectChanges(); await fixture.whenStable(); @@ -295,7 +295,7 @@ describe('DropdownSitesComponent', () => { }); it('should show all the sites if no relation is set', async () => { - spyOn(authService, 'getEcmUsername').and.returnValue('test'); + spyOn(authService, 'getUsername').and.returnValue('test'); fixture.detectChanges(); await fixture.whenStable(); diff --git a/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.ts b/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.ts index 2c402bd46c..94402bdc13 100644 --- a/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.ts +++ b/lib/content-services/src/lib/content-node-selector/site-dropdown/sites-dropdown.component.ts @@ -182,7 +182,7 @@ export class DropdownSitesComponent implements OnInit { } private filteredResultsByMember(sites: SitePaging): SitePaging { - const loggedUserName = this.authService.getEcmUsername(); + const loggedUserName = this.authService.getUsername(); sites.list.entries = sites.list.entries.filter((site) => this.isCurrentUserMember(site, loggedUserName)); return sites; } diff --git a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts index d827435f1a..66f10297e2 100644 --- a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts +++ b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts @@ -646,7 +646,7 @@ describe('DocumentList', () => { title: 'FileAction' }); - spyOn(authenticationService, 'getEcmUsername').and.returnValue('lockOwner'); + spyOn(authenticationService, 'getUsername').and.returnValue('lockOwner'); documentList.actions = [documentMenu]; @@ -677,7 +677,7 @@ describe('DocumentList', () => { title: 'FileAction' }); - spyOn(authenticationService, 'getEcmUsername').and.returnValue('jerryTheKillerCow'); + spyOn(authenticationService, 'getUsername').and.returnValue('jerryTheKillerCow'); documentList.actions = [documentMenu]; diff --git a/lib/content-services/src/lib/document-list/services/lock.service.spec.ts b/lib/content-services/src/lib/document-list/services/lock.service.spec.ts index 83ef034a1f..d915f877a4 100644 --- a/lib/content-services/src/lib/document-list/services/lock.service.spec.ts +++ b/lib/content-services/src/lib/document-list/services/lock.service.spec.ts @@ -137,22 +137,22 @@ describe('LockService', () => { } as Node; it('should return false when the user is the lock owner', () => { - spyOn(authenticationService, 'getEcmUsername').and.returnValue('lock-owner-user'); + spyOn(authenticationService, 'getUsername').and.returnValue('lock-owner-user'); expect(service.isLocked(nodeOwnerAllowedLock)).toBeFalsy(); }); it('should return true when the user is not the lock owner', () => { - spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user'); + spyOn(authenticationService, 'getUsername').and.returnValue('banana-user'); expect(service.isLocked(nodeOwnerAllowedLock)).toBeTruthy(); }); it('should return false when the user is not the lock owner but the lock is expired', () => { - spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user'); + spyOn(authenticationService, 'getUsername').and.returnValue('banana-user'); expect(service.isLocked(nodeOwnerAllowedLockWithExpiredDate)).toBeFalsy(); }); it('should return true when is not the lock owner and the expiration date is valid', () => { - spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user'); + spyOn(authenticationService, 'getUsername').and.returnValue('banana-user'); expect(service.isLocked(nodeOwnerAllowedLockWithActiveExpiration)).toBeTruthy(); }); }); diff --git a/lib/content-services/src/lib/document-list/services/lock.service.ts b/lib/content-services/src/lib/document-list/services/lock.service.ts index 6653c6e3bc..8e2bfec303 100644 --- a/lib/content-services/src/lib/document-list/services/lock.service.ts +++ b/lib/content-services/src/lib/document-list/services/lock.service.ts @@ -32,7 +32,7 @@ export class LockService { if (this.isReadOnlyLock(node)) { isLocked = !this.isLockExpired(node); } else if (this.isLockOwnerAllowed(node)) { - isLocked = this.authService.getEcmUsername() !== node.properties['cm:lockOwner'].id; + isLocked = this.authService.getUsername() !== node.properties['cm:lockOwner'].id; if (this.isLockExpired(node)) { isLocked = false; } diff --git a/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts b/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts index ba788d3d98..049a253a23 100644 --- a/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts +++ b/lib/core/src/lib/auth/guard/auth-guard-bpm.service.ts @@ -28,7 +28,7 @@ export const AuthGuardBpm: CanActivateFn = async (_: ActivatedRouteSnapshot, sta return authGuardBaseService.redirectSSOSuccessURL(); } - if (authenticationService.isBpmLoggedIn() || authGuardBaseService.withCredentials) { + if (authenticationService.isLoggedIn() || authGuardBaseService.withCredentials) { return true; } diff --git a/lib/core/src/lib/auth/interfaces/authentication-service.interface.ts b/lib/core/src/lib/auth/interfaces/authentication-service.interface.ts index 06d21bc7f8..1c94bec7a2 100644 --- a/lib/core/src/lib/auth/interfaces/authentication-service.interface.ts +++ b/lib/core/src/lib/auth/interfaces/authentication-service.interface.ts @@ -20,7 +20,6 @@ import ee from 'event-emitter'; import { Observable } from 'rxjs'; export interface AuthenticationServiceInterface { - onError: any; onLogin: any; onLogout: any; @@ -31,30 +30,26 @@ export interface AuthenticationServiceInterface { emit: (type: string, ...args: any[]) => void; getToken(): string; - isLoggedIn(): boolean; - isOauth(): boolean; - logout(): any; - isEcmLoggedIn(): boolean; - - isBpmLoggedIn(): boolean; - isECMProvider(): boolean; - isBPMProvider(): boolean; - isALLProvider(): boolean; - - getEcmUsername(): string; - - getBpmUsername(): string; + getUsername(): string; getAuthHeaders(requestUrl: string, header: HttpHeaders): HttpHeaders; - addTokenToHeader(requestUrl: string, headersArg?: HttpHeaders): Observable; - reset(): void; + + /** @deprecated use `isLoggedIn` instead, use `isECMProvider` if you need to know the auth type */ + isEcmLoggedIn(): boolean; + /** @deprecated use `isLoggedIn` instead, use `isBPMProvider` if you need to know the auth type */ + isBpmLoggedIn(): boolean; + + /** @deprecated use `getUsername` instead */ + getEcmUsername(): string; + /** @deprecated use `getUsername` instead */ + getBpmUsername(): string; } diff --git a/lib/core/src/lib/auth/oidc/oidc-authentication.service.ts b/lib/core/src/lib/auth/oidc/oidc-authentication.service.ts index 9d0eb77fdf..06c3df2f37 100644 --- a/lib/core/src/lib/auth/oidc/oidc-authentication.service.ts +++ b/lib/core/src/lib/auth/oidc/oidc-authentication.service.ts @@ -56,6 +56,10 @@ export class OidcAuthenticationService extends BaseAuthenticationService { map(([authenticated, isDiscoveryDocumentLoaded]) => !authenticated && isDiscoveryDocumentLoaded) ); + /** + * @deprecated use `isLoggedIn` instead + * @returns true if the ECM provider is logged in + */ isEcmLoggedIn(): boolean { if (this.isECMProvider() || this.isALLProvider()) { return this.isLoggedIn(); @@ -63,6 +67,10 @@ export class OidcAuthenticationService extends BaseAuthenticationService { return false; } + /** + * @deprecated use `isLoggedIn` instead + * @returns true if the BPM provider is logged in + */ isBpmLoggedIn(): boolean { if (this.isBPMProvider() || this.isALLProvider()) { return this.isLoggedIn(); diff --git a/lib/core/src/lib/auth/services/authentication.service.ts b/lib/core/src/lib/auth/services/authentication.service.ts index 31b437db13..a0caca3641 100644 --- a/lib/core/src/lib/auth/services/authentication.service.ts +++ b/lib/core/src/lib/auth/services/authentication.service.ts @@ -116,6 +116,10 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee } } + /** + * @deprecated use `isLoggedIn` instead + * @returns true if the ECM provider is logged in + */ isEcmLoggedIn(): boolean { if (this.isOauth()) { return this.oidcAuthenticationService.isEcmLoggedIn(); @@ -124,6 +128,10 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee } } + /** + * @deprecated use `isLoggedIn` instead + * @returns true if the BPM provider is logged in + */ isBpmLoggedIn(): boolean { if (this.isOauth()) { return this.oidcAuthenticationService.isBpmLoggedIn(); @@ -166,11 +174,7 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee * @returns the logged username */ getEcmUsername(): string { - if (this.isOauth()) { - return this.oidcAuthenticationService.getUsername(); - } else { - return this.basicAlfrescoAuthService.getEcmUsername(); - } + return this.getUsername(); } /** @@ -178,11 +182,7 @@ export class AuthenticationService implements AuthenticationServiceInterface, ee * @returns the logged username */ getBpmUsername(): string { - if (this.isOauth()) { - return this.oidcAuthenticationService.getUsername(); - } else { - return this.basicAlfrescoAuthService.getBpmUsername(); - } + return this.getUsername(); } getAuthHeaders(requestUrl: string, headers: HttpHeaders): HttpHeaders { diff --git a/lib/core/src/lib/auth/services/base-authentication.service.ts b/lib/core/src/lib/auth/services/base-authentication.service.ts index f7f9be6ad7..3a88d23301 100644 --- a/lib/core/src/lib/auth/services/base-authentication.service.ts +++ b/lib/core/src/lib/auth/services/base-authentication.service.ts @@ -51,7 +51,6 @@ export abstract class BaseAuthenticationService implements AuthenticationService abstract isBpmLoggedIn(): boolean; abstract reset(): void; - abstract getUsername(): string; /** @deprecated use `getUsername` instead */