mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Redirect to sign-in page when user session timed out (#16005)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
0a845d6369
commit
21dfba7330
@ -51,3 +51,4 @@ export class SignInService {
|
||||
}
|
||||
|
||||
export const UN_LOGGED_PARAM: string = 'publicAndNotLogged';
|
||||
export const YES: string = 'yes';
|
||||
|
@ -48,7 +48,7 @@ import { errorHandler } from "../../../../../../../shared/units/shared.utils";
|
||||
import { ConfirmationDialogComponent } from "../../../../../../../shared/components/confirmation-dialog";
|
||||
import { ConfirmationMessage } from "../../../../../../global-confirmation-dialog/confirmation-message";
|
||||
import { ConfirmationAcknowledgement } from "../../../../../../global-confirmation-dialog/confirmation-state-message";
|
||||
import { UN_LOGGED_PARAM } from "../../../../../../../account/sign-in/sign-in.service";
|
||||
import { UN_LOGGED_PARAM, YES } from "../../../../../../../account/sign-in/sign-in.service";
|
||||
import { Label } from "../../../../../../../../../ng-swagger-gen/models/label";
|
||||
import { LabelService } from "../../../../../../../../../ng-swagger-gen/services/label.service";
|
||||
import { EventService, HarborEvent } from "../../../../../../../services/event-service/event.service";
|
||||
@ -59,7 +59,6 @@ export interface LabelState {
|
||||
show: boolean;
|
||||
}
|
||||
export const AVAILABLE_TIME = '0001-01-01T00:00:00.000Z';
|
||||
const YES: string = 'yes';
|
||||
const PAGE_SIZE: number = 100;
|
||||
@Component({
|
||||
selector: 'artifact-list-tab',
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ElementRef } from '@angular/core';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { ClarityModule } from '@clr/angular';
|
||||
import { Message } from './message';
|
||||
import { MessageService } from './message.service';
|
||||
import { MessageComponent } from './message.component';
|
||||
import { AlertType } from "../../entities/shared.const";
|
||||
import { SharedTestingModule } from "../../shared.module";
|
||||
|
||||
describe('MessageComponent', () => {
|
||||
let component: MessageComponent;
|
||||
@ -16,14 +13,10 @@ describe('MessageComponent', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
ClarityModule,
|
||||
RouterTestingModule,
|
||||
TranslateModule.forRoot()
|
||||
SharedTestingModule
|
||||
],
|
||||
declarations: [MessageComponent],
|
||||
providers: [
|
||||
MessageService,
|
||||
TranslateService,
|
||||
{provide: ElementRef, useValue: fakeElementRef}
|
||||
]
|
||||
}).compileComponents();
|
||||
|
@ -19,9 +19,9 @@ import { Message } from './message';
|
||||
import { MessageService } from './message.service';
|
||||
import { CommonRoutes, dismissInterval, httpStatusCode } from "../../entities/shared.const";
|
||||
import { delUrlParam } from "../../units/utils";
|
||||
import { UN_LOGGED_PARAM } from "../../../account/sign-in/sign-in.service";
|
||||
import { UN_LOGGED_PARAM, YES } from "../../../account/sign-in/sign-in.service";
|
||||
import { SessionService } from "../../services/session.service";
|
||||
|
||||
const YES: string = 'yes';
|
||||
@Component({
|
||||
selector: 'global-message',
|
||||
templateUrl: 'message.component.html',
|
||||
@ -44,7 +44,8 @@ export class MessageComponent implements OnInit, OnDestroy {
|
||||
private messageService: MessageService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private translate: TranslateService) { }
|
||||
private translate: TranslateService,
|
||||
private session: SessionService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
// Only subscribe application level message
|
||||
@ -53,6 +54,7 @@ export class MessageComponent implements OnInit, OnDestroy {
|
||||
message => {
|
||||
this.globalMessageOpened = true;
|
||||
this.globalMessage = message;
|
||||
this.checkLoginStatus();
|
||||
this.messageText = message.message;
|
||||
|
||||
this.translateMessage(message);
|
||||
@ -64,6 +66,7 @@ export class MessageComponent implements OnInit, OnDestroy {
|
||||
message => {
|
||||
this.globalMessageOpened = true;
|
||||
this.globalMessage = message;
|
||||
this.checkLoginStatus();
|
||||
this.messageText = message.message;
|
||||
|
||||
this.translateMessage(message);
|
||||
@ -148,4 +151,18 @@ export class MessageComponent implements OnInit, OnDestroy {
|
||||
isFromGlobalSearch(): boolean {
|
||||
return this.route.snapshot.queryParams[UN_LOGGED_PARAM] === YES;
|
||||
}
|
||||
checkLoginStatus() {
|
||||
if (this.globalMessage.statusCode === httpStatusCode.Unauthorized) {
|
||||
// User session timed out, then redirect to sign-in page
|
||||
if (this.session.getCurrentUser() && !this.isSignInUrl() && this.route.snapshot.queryParams[UN_LOGGED_PARAM] !== YES) {
|
||||
const url = delUrlParam(this.router.url, UN_LOGGED_PARAM);
|
||||
this.session.clear(); // because of SignInGuard, must clear user session before navigating to sign-in page
|
||||
this.router.navigate([ CommonRoutes.EMBEDDED_SIGN_IN ], {queryParams: {redirect_url: url}});
|
||||
}
|
||||
}
|
||||
}
|
||||
isSignInUrl(): boolean {
|
||||
const url: string = this.router.url?.indexOf('?') === -1 ? this.router.url : this.router.url?.split('?')[0];
|
||||
return url === CommonRoutes.EMBEDDED_SIGN_IN;
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ import { Router } from '@angular/router';
|
||||
import { Repository } from '../../../../../ng-swagger-gen/models/repository';
|
||||
import { SearchTriggerService } from '../global-search/search-trigger.service';
|
||||
import { SessionService } from "../../services/session.service";
|
||||
import { UN_LOGGED_PARAM } from "../../../account/sign-in/sign-in.service";
|
||||
|
||||
const YES: string = 'yes';
|
||||
import { UN_LOGGED_PARAM, YES } from "../../../account/sign-in/sign-in.service";
|
||||
|
||||
@Component({
|
||||
selector: 'list-repository-ro',
|
||||
|
@ -23,6 +23,9 @@ import { Observable, of } from 'rxjs';
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
import { ProjectService } from "../services";
|
||||
import { CommonRoutes } from "../entities/shared.const";
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import { delUrlParam } from "../units/utils";
|
||||
import { UN_LOGGED_PARAM, YES } from 'src/app/account/sign-in/sign-in.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -39,12 +42,12 @@ export class MemberGuard implements CanActivate, CanActivateChild {
|
||||
|
||||
const user = this.sessionService.getCurrentUser();
|
||||
if (user !== null) {
|
||||
return this.hasProjectPerm(state.url, projectId);
|
||||
return this.hasProjectPerm(state.url, projectId, route);
|
||||
}
|
||||
|
||||
return this.sessionService.retrieveUser().pipe(
|
||||
() => {
|
||||
return this.hasProjectPerm(state.url, projectId);
|
||||
return this.hasProjectPerm(state.url, projectId, route);
|
||||
},
|
||||
catchError(err => {
|
||||
this.router.navigate([CommonRoutes.HARBOR_DEFAULT]);
|
||||
@ -57,14 +60,21 @@ export class MemberGuard implements CanActivate, CanActivateChild {
|
||||
return this.canActivate(route, state);
|
||||
}
|
||||
|
||||
hasProjectPerm(url: string, projectId: number): Observable<boolean> {
|
||||
hasProjectPerm(url: string, projectId: number, route: ActivatedRouteSnapshot): Observable<boolean> {
|
||||
// Note: current user will have the permission to visit the project when the user can get response from GET /projects/:id API.
|
||||
return this.projectService.getProject(projectId).pipe(
|
||||
map(() => {
|
||||
return true;
|
||||
}),
|
||||
catchError(err => {
|
||||
// User session timed out, then redirect to sign-in page
|
||||
if (err.status === HttpStatusCode.Unauthorized && route.queryParams[UN_LOGGED_PARAM] !== YES) {
|
||||
this.sessionService.clear(); // because of SignInGuard, must clear user session before navigating to sign-in page
|
||||
this.router.navigate([ CommonRoutes.EMBEDDED_SIGN_IN ],
|
||||
{queryParams: {redirect_url: delUrlParam(this.router.url, UN_LOGGED_PARAM)}});
|
||||
} else {
|
||||
this.router.navigate([CommonRoutes.HARBOR_DEFAULT]);
|
||||
}
|
||||
return of(false);
|
||||
})
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user