Skip to content

Commit cfb77b2

Browse files
committed
KNOX-3187 - Show pop-up window on Token Management/Generation pages when Knox token hash key is missing (apache#1082)
1 parent 890ebc7 commit cfb77b2

File tree

5 files changed

+101
-15
lines changed

5 files changed

+101
-15
lines changed

knox-token-generation-ui/token-generation/app/token-generation.component.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export class TokenGenerationComponent implements OnInit {
6868
// Data coming from TokenStateService status request
6969
tssStatus: TssStatusData;
7070

71+
7172
constructor(private http: HttpClient, private tokenGenService: TokenGenService) {
7273
this.tssStatusMessageLevel = 'info';
7374
this.tssStatusMessage = '';
@@ -79,7 +80,14 @@ export class TokenGenerationComponent implements OnInit {
7980
}
8081

8182
ngOnInit(): void {
82-
this.setTokenStateServiceStatus();
83+
this.tokenGenService.isTokenHashKeyPresent().then(
84+
tokenHashKeyPresent => {
85+
if (tokenHashKeyPresent) {
86+
this.setTokenStateServiceStatus();
87+
} else {
88+
this.showMissingKnoxTokenHashKeyPopup();
89+
}
90+
});
8391
}
8492

8593
generateToken() {
@@ -110,13 +118,13 @@ export class TokenGenerationComponent implements OnInit {
110118

111119
setTokenStateServiceStatus() {
112120
this.tokenGenService.getTokenStateServiceStatus()
113-
.then(tssStatus => {
114-
this.tssStatus = tssStatus;
115-
this.decideTssMessage();
116-
})
117-
.catch((errorMessage) => {
118-
this.requestErrorMessage = errorMessage;
119-
});
121+
.then(tssStatus => {
122+
this.tssStatus = tssStatus;
123+
this.decideTssMessage();
124+
})
125+
.catch((errorMessage) => {
126+
this.requestErrorMessage = errorMessage;
127+
});
120128
}
121129

122130
copyTextToClipboard(elementId) {
@@ -206,4 +214,14 @@ export class TokenGenerationComponent implements OnInit {
206214
this.tssStatusMessageLevel = level;
207215
this.tssStatusMessage = message;
208216
}
217+
218+
private showMissingKnoxTokenHashKeyPopup(): void {
219+
const message = 'The required gateway-level alias, knox.token.hash.key, is missing.';
220+
Swal.fire({
221+
icon: 'warning',
222+
title: 'Token Generation Disabled!',
223+
text: message,
224+
confirmButtonColor: '#7cd1f9'
225+
});
226+
}
209227
}

knox-token-generation-ui/token-generation/app/token-generation.service.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class TokenGenService {
2525
readonly tokenURL: string;
2626
readonly tssStatusRequestURL: string;
2727
readonly sessionUrl: string;
28+
readonly metadataInfoUrl: string;
2829

2930
constructor(private http: HttpClient) {
3031
const knoxtokenURL = 'knoxtoken/api/v2/token';
@@ -37,6 +38,7 @@ export class TokenGenService {
3738
this.tokenURL = topologyContext + knoxtokenURL;
3839
this.tssStatusRequestURL = topologyContext + tssStatusURL;
3940
this.sessionUrl = topologyContext + 'session/api/v1/sessioninfo';
41+
this.metadataInfoUrl = topologyContext + 'api/v1/metadata/info';
4042
}
4143

4244
getTokenStateServiceStatus(): Promise<TssStatusData> {
@@ -73,14 +75,31 @@ export class TokenGenService {
7375
});
7476
}
7577

78+
isTokenHashKeyPresent(): Promise<boolean> {
79+
let headers = new HttpHeaders();
80+
headers = this.addHeaders(headers);
81+
return this.http.get(this.metadataInfoUrl, { headers: headers})
82+
.toPromise()
83+
.then(response => {
84+
return response['generalProxyInfo']?.['enableTokenManagement'] === 'true';
85+
})
86+
.catch((err: HttpErrorResponse) => {
87+
console.debug('TokenGenService --> isTokenHashKeyPresent() --> ' + this.metadataInfoUrl + '\n error: ' + err.message);
88+
if (err.status === 401) {
89+
window.location.assign(document.location.pathname);
90+
} else {
91+
return this.handleError(err);
92+
}
93+
});
94+
}
7695
getSessionInformation(): Promise<SessionInformation> {
7796
let headers = new HttpHeaders();
7897
headers = this.addHeaders(headers);
7998
return this.http.get(this.sessionUrl, { headers: headers})
8099
.toPromise()
81100
.then(response => response['sessioninfo'] as SessionInformation)
82101
.catch((err: HttpErrorResponse) => {
83-
console.debug('TokenManagementService --> getSessionInformation() --> ' + this.sessionUrl + '\n error: ' + err.message);
102+
console.debug('TokenGenService --> getSessionInformation() --> ' + this.sessionUrl + '\n error: ' + err.message);
84103
if (err.status === 401) {
85104
window.location.assign(document.location.pathname);
86105
} else {

knox-token-management-ui/token-management/app/token.management.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@
1515
<div>
1616

1717
<div>
18-
<button (click)="gotoTokenGenerationPage();">Generate New Token</button>
19-
<button type="button" title="Refresh Knox Tokens" (click)="fetchKnoxTokens();">
18+
<button (click)="gotoTokenGenerationPage();" [disabled]="!isTokenHashKeyPresent()">Generate New Token</button>
19+
<button type="button" title="Refresh Knox Tokens" (click)="fetchKnoxTokens();" [disabled]="!isTokenHashKeyPresent()">
2020
<span class="glyphicon glyphicon-refresh"></span>
2121
</button>
2222
<span style="float: right;">
23-
<mat-slide-toggle (change)="onChangeShowDisabledCookies($event)" [(ngModel)]="showDisabledKnoxSsoCookies">
23+
<mat-slide-toggle (change)="onChangeShowDisabledCookies($event)" [(ngModel)]="showDisabledKnoxSsoCookies" [disabled]="!isTokenHashKeyPresent()">
2424
Show Disabled KnoxSSO Cookies
2525
</mat-slide-toggle>
2626
</span>
2727
</div>
2828

2929
<div *ngIf="userCanSeeAllTokens()">
3030
<span style="float: right;">
31-
<mat-slide-toggle (change)="onChangeShowMyTokensOnly($event)" [(ngModel)]="showMyTokensOnly">
31+
<mat-slide-toggle (change)="onChangeShowMyTokensOnly($event)" [(ngModel)]="showMyTokensOnly" [disabled]="!isTokenHashKeyPresent()">
3232
Show My Tokens Only
3333
</mat-slide-toggle>
3434
</span>

knox-token-management-ui/token-management/app/token.management.component.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {MatPaginator} from '@angular/material/paginator';
2222
import {MatSort} from '@angular/material/sort';
2323
import {MatSlideToggleChange} from '@angular/material/slide-toggle';
2424
import {SelectionModel} from '@angular/cdk/collections';
25+
import Swal from 'sweetalert2';
2526

2627
@Component({
2728
selector: 'app-token-management',
@@ -39,6 +40,7 @@ export class TokenManagementComponent implements OnInit {
3940
userName: string;
4041
canSeeAllTokens: boolean;
4142
currentKnoxSsoCookieTokenId: string;
43+
tokenHashKeyPresent: boolean;
4244
knoxTokens: MatTableDataSource<KnoxToken> = new MatTableDataSource();
4345
selection = new SelectionModel<KnoxToken>(true, []);
4446
allKnoxTokens: KnoxToken[];
@@ -103,6 +105,15 @@ export class TokenManagementComponent implements OnInit {
103105

104106
ngOnInit(): void {
105107
console.debug('TokenManagementComponent --> ngOnInit()');
108+
this.tokenManagementService.isTokenHashKeyPresent().then(
109+
tokenHashKeyPresent => {
110+
this.tokenHashKeyPresent = tokenHashKeyPresent;
111+
if (!tokenHashKeyPresent) {
112+
this.showMissingKnoxTokenHashKeyPopup();
113+
}
114+
}
115+
);
116+
106117
this.tokenManagementService.getSessionInformation()
107118
.then(sessionInformation => {
108119
this.canSeeAllTokens = sessionInformation.canSeeAllTokens;
@@ -111,6 +122,10 @@ export class TokenManagementComponent implements OnInit {
111122
});
112123
}
113124

125+
isTokenHashKeyPresent(): boolean{
126+
return this.tokenHashKeyPresent;
127+
}
128+
114129
setUserName(userName: string) {
115130
this.userName = userName;
116131
this.fetchKnoxTokens();
@@ -121,8 +136,12 @@ export class TokenManagementComponent implements OnInit {
121136
}
122137

123138
fetchKnoxTokens(): void {
124-
this.tokenManagementService.getKnoxTokens(this.userName, this.canSeeAllTokens)
125-
.then(tokens => this.updateTokens(tokens));
139+
if (this.tokenHashKeyPresent) {
140+
this.tokenManagementService.getKnoxTokens(this.userName, this.canSeeAllTokens)
141+
.then(tokens => this.updateTokens(tokens));
142+
} else {
143+
console.debug('knox.token.hash.key is missing, skipping Knox token fetch...');
144+
}
126145
}
127146

128147
private isMyToken(token: KnoxToken): boolean {
@@ -284,4 +303,14 @@ export class TokenManagementComponent implements OnInit {
284303
return this.isKnoxSsoCookie(token) && token.tokenId === this.currentKnoxSsoCookieTokenId;
285304
}
286305

306+
private showMissingKnoxTokenHashKeyPopup(): void {
307+
const message = 'The required gateway-level alias, knox.token.hash.key, is missing.';
308+
Swal.fire({
309+
icon: 'warning',
310+
title: 'Token Management Disabled!',
311+
text: message,
312+
confirmButtonColor: '#7cd1f9'
313+
});
314+
}
315+
287316
}

knox-token-management-ui/token-management/app/token.management.service.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export class TokenManagementService {
3838
revokeKnoxTokenUrl = this.apiUrl + 'revoke';
3939
revokeKnoxTokensBatchUrl = this.apiUrl + 'revokeTokens';
4040
getTssStatusUrl = this.apiUrl + 'getTssStatus';
41+
metadataInfoUrl = this.topologyContext + 'api/v1/metadata/info';
4142

4243
constructor(private http: HttpClient) {}
4344

@@ -129,6 +130,25 @@ export class TokenManagementService {
129130
});
130131
}
131132

133+
isTokenHashKeyPresent(): Promise<boolean> {
134+
let headers = new HttpHeaders();
135+
headers = this.addJsonHeaders(headers);
136+
return this.http.get(this.metadataInfoUrl, { headers: headers})
137+
.toPromise()
138+
.then(response => {
139+
return response['generalProxyInfo']?.['enableTokenManagement'] === 'true';
140+
})
141+
.catch((err: HttpErrorResponse) => {
142+
console.debug('TokenManagementService --> isTokenHashKeyPresent() --> '
143+
+ this.metadataInfoUrl + '\n error: ' + err.message);
144+
if (err.status === 401) {
145+
window.location.assign(document.location.pathname);
146+
} else {
147+
return this.handleError(err);
148+
}
149+
});
150+
}
151+
132152
getSessionInformation(): Promise<SessionInformation> {
133153
let headers = new HttpHeaders();
134154
headers = this.addJsonHeaders(headers);

0 commit comments

Comments
 (0)