This is an automated email from the ASF dual-hosted git repository.
smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new fda911198 KNOX-3187 - Show pop-up window on Token
Management/Generation pages when Knox token hash key is missing (#1082)
fda911198 is described below
commit fda91119814b84b1e8bfa7ac95755e25c0f7d85e
Author: Sandor Molnar <[email protected]>
AuthorDate: Tue Sep 9 15:42:42 2025 +0200
KNOX-3187 - Show pop-up window on Token Management/Generation pages when
Knox token hash key is missing (#1082)
---
.../app/token-generation.component.ts | 34 +++++++++++++++++-----
.../app/token-generation.service.ts | 21 ++++++++++++-
.../app/token.management.component.html | 8 ++---
.../app/token.management.component.ts | 33 +++++++++++++++++++--
.../app/token.management.service.ts | 20 +++++++++++++
5 files changed, 101 insertions(+), 15 deletions(-)
diff --git
a/knox-token-generation-ui/token-generation/app/token-generation.component.ts
b/knox-token-generation-ui/token-generation/app/token-generation.component.ts
index e155fc931..4eb703089 100644
---
a/knox-token-generation-ui/token-generation/app/token-generation.component.ts
+++
b/knox-token-generation-ui/token-generation/app/token-generation.component.ts
@@ -68,6 +68,7 @@ export class TokenGenerationComponent implements OnInit {
// Data coming from TokenStateService status request
tssStatus: TssStatusData;
+
constructor(private http: HttpClient, private tokenGenService:
TokenGenService) {
this.tssStatusMessageLevel = 'info';
this.tssStatusMessage = '';
@@ -79,7 +80,14 @@ export class TokenGenerationComponent implements OnInit {
}
ngOnInit(): void {
- this.setTokenStateServiceStatus();
+ this.tokenGenService.isTokenHashKeyPresent().then(
+ tokenHashKeyPresent => {
+ if (tokenHashKeyPresent) {
+ this.setTokenStateServiceStatus();
+ } else {
+ this.showMissingKnoxTokenHashKeyPopup();
+ }
+ });
}
generateToken() {
@@ -110,13 +118,13 @@ export class TokenGenerationComponent implements OnInit {
setTokenStateServiceStatus() {
this.tokenGenService.getTokenStateServiceStatus()
- .then(tssStatus => {
- this.tssStatus = tssStatus;
- this.decideTssMessage();
- })
- .catch((errorMessage) => {
- this.requestErrorMessage = errorMessage;
- });
+ .then(tssStatus => {
+ this.tssStatus = tssStatus;
+ this.decideTssMessage();
+ })
+ .catch((errorMessage) => {
+ this.requestErrorMessage = errorMessage;
+ });
}
copyTextToClipboard(elementId) {
@@ -206,4 +214,14 @@ export class TokenGenerationComponent implements OnInit {
this.tssStatusMessageLevel = level;
this.tssStatusMessage = message;
}
+
+ private showMissingKnoxTokenHashKeyPopup(): void {
+ const message = 'The required gateway-level alias, knox.token.hash.key, is
missing.';
+ Swal.fire({
+ icon: 'warning',
+ title: 'Token Generation Disabled!',
+ text: message,
+ confirmButtonColor: '#7cd1f9'
+ });
+ }
}
diff --git
a/knox-token-generation-ui/token-generation/app/token-generation.service.ts
b/knox-token-generation-ui/token-generation/app/token-generation.service.ts
index f315988f7..7122336e6 100644
--- a/knox-token-generation-ui/token-generation/app/token-generation.service.ts
+++ b/knox-token-generation-ui/token-generation/app/token-generation.service.ts
@@ -25,6 +25,7 @@ export class TokenGenService {
readonly tokenURL: string;
readonly tssStatusRequestURL: string;
readonly sessionUrl: string;
+ readonly metadataInfoUrl: string;
constructor(private http: HttpClient) {
const knoxtokenURL = 'knoxtoken/api/v2/token';
@@ -37,6 +38,7 @@ export class TokenGenService {
this.tokenURL = topologyContext + knoxtokenURL;
this.tssStatusRequestURL = topologyContext + tssStatusURL;
this.sessionUrl = topologyContext + 'session/api/v1/sessioninfo';
+ this.metadataInfoUrl = topologyContext + 'api/v1/metadata/info';
}
getTokenStateServiceStatus(): Promise<TssStatusData> {
@@ -73,6 +75,23 @@ export class TokenGenService {
});
}
+ isTokenHashKeyPresent(): Promise<boolean> {
+ let headers = new HttpHeaders();
+ headers = this.addHeaders(headers);
+ return this.http.get(this.metadataInfoUrl, { headers: headers})
+ .toPromise()
+ .then(response => {
+ return response['generalProxyInfo']?.['enableTokenManagement']
=== 'true';
+ })
+ .catch((err: HttpErrorResponse) => {
+ console.debug('TokenGenService --> isTokenHashKeyPresent() -->
' + this.metadataInfoUrl + '\n error: ' + err.message);
+ if (err.status === 401) {
+ window.location.assign(document.location.pathname);
+ } else {
+ return this.handleError(err);
+ }
+ });
+ }
getSessionInformation(): Promise<SessionInformation> {
let headers = new HttpHeaders();
headers = this.addHeaders(headers);
@@ -80,7 +99,7 @@ export class TokenGenService {
.toPromise()
.then(response => response['sessioninfo'] as SessionInformation)
.catch((err: HttpErrorResponse) => {
- console.debug('TokenManagementService -->
getSessionInformation() --> ' + this.sessionUrl + '\n error: ' + err.message);
+ console.debug('TokenGenService --> getSessionInformation() -->
' + this.sessionUrl + '\n error: ' + err.message);
if (err.status === 401) {
window.location.assign(document.location.pathname);
} else {
diff --git
a/knox-token-management-ui/token-management/app/token.management.component.html
b/knox-token-management-ui/token-management/app/token.management.component.html
index be371c4e9..6260b964c 100644
---
a/knox-token-management-ui/token-management/app/token.management.component.html
+++
b/knox-token-management-ui/token-management/app/token.management.component.html
@@ -15,12 +15,12 @@
<div>
<div>
- <button (click)="gotoTokenGenerationPage();">Generate New
Token</button>
- <button type="button" title="Refresh Knox Tokens"
(click)="fetchKnoxTokens();">
+ <button (click)="gotoTokenGenerationPage();"
[disabled]="!isTokenHashKeyPresent()">Generate New Token</button>
+ <button type="button" title="Refresh Knox Tokens"
(click)="fetchKnoxTokens();" [disabled]="!isTokenHashKeyPresent()">
<span class="glyphicon glyphicon-refresh"></span>
</button>
<span style="float: right;">
- <mat-slide-toggle (change)="onChangeShowDisabledCookies($event)"
[(ngModel)]="showDisabledKnoxSsoCookies">
+ <mat-slide-toggle (change)="onChangeShowDisabledCookies($event)"
[(ngModel)]="showDisabledKnoxSsoCookies" [disabled]="!isTokenHashKeyPresent()">
Show Disabled KnoxSSO Cookies
</mat-slide-toggle>
</span>
@@ -28,7 +28,7 @@
<div *ngIf="userCanSeeAllTokens()">
<span style="float: right;">
- <mat-slide-toggle (change)="onChangeShowMyTokensOnly($event)"
[(ngModel)]="showMyTokensOnly">
+ <mat-slide-toggle (change)="onChangeShowMyTokensOnly($event)"
[(ngModel)]="showMyTokensOnly" [disabled]="!isTokenHashKeyPresent()">
Show My Tokens Only
</mat-slide-toggle>
</span>
diff --git
a/knox-token-management-ui/token-management/app/token.management.component.ts
b/knox-token-management-ui/token-management/app/token.management.component.ts
index 903ecd5d0..74777b7a4 100644
---
a/knox-token-management-ui/token-management/app/token.management.component.ts
+++
b/knox-token-management-ui/token-management/app/token.management.component.ts
@@ -22,6 +22,7 @@ import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {MatSlideToggleChange} from '@angular/material/slide-toggle';
import {SelectionModel} from '@angular/cdk/collections';
+import Swal from 'sweetalert2';
@Component({
selector: 'app-token-management',
@@ -39,6 +40,7 @@ export class TokenManagementComponent implements OnInit {
userName: string;
canSeeAllTokens: boolean;
currentKnoxSsoCookieTokenId: string;
+ tokenHashKeyPresent: boolean;
knoxTokens: MatTableDataSource<KnoxToken> = new MatTableDataSource();
selection = new SelectionModel<KnoxToken>(true, []);
allKnoxTokens: KnoxToken[];
@@ -103,6 +105,15 @@ export class TokenManagementComponent implements OnInit {
ngOnInit(): void {
console.debug('TokenManagementComponent --> ngOnInit()');
+ this.tokenManagementService.isTokenHashKeyPresent().then(
+ tokenHashKeyPresent => {
+ this.tokenHashKeyPresent = tokenHashKeyPresent;
+ if (!tokenHashKeyPresent) {
+ this.showMissingKnoxTokenHashKeyPopup();
+ }
+ }
+ );
+
this.tokenManagementService.getSessionInformation()
.then(sessionInformation => {
this.canSeeAllTokens = sessionInformation.canSeeAllTokens;
@@ -111,6 +122,10 @@ export class TokenManagementComponent implements OnInit {
});
}
+ isTokenHashKeyPresent(): boolean{
+ return this.tokenHashKeyPresent;
+ }
+
setUserName(userName: string) {
this.userName = userName;
this.fetchKnoxTokens();
@@ -121,8 +136,12 @@ export class TokenManagementComponent implements OnInit {
}
fetchKnoxTokens(): void {
- this.tokenManagementService.getKnoxTokens(this.userName,
this.canSeeAllTokens)
- .then(tokens => this.updateTokens(tokens));
+ if (this.tokenHashKeyPresent) {
+ this.tokenManagementService.getKnoxTokens(this.userName,
this.canSeeAllTokens)
+ .then(tokens => this.updateTokens(tokens));
+ } else {
+ console.debug('knox.token.hash.key is missing, skipping Knox token
fetch...');
+ }
}
private isMyToken(token: KnoxToken): boolean {
@@ -284,4 +303,14 @@ export class TokenManagementComponent implements OnInit {
return this.isKnoxSsoCookie(token) && token.tokenId ===
this.currentKnoxSsoCookieTokenId;
}
+ private showMissingKnoxTokenHashKeyPopup(): void {
+ const message = 'The required gateway-level alias,
knox.token.hash.key, is missing.';
+ Swal.fire({
+ icon: 'warning',
+ title: 'Token Management Disabled!',
+ text: message,
+ confirmButtonColor: '#7cd1f9'
+ });
+ }
+
}
diff --git
a/knox-token-management-ui/token-management/app/token.management.service.ts
b/knox-token-management-ui/token-management/app/token.management.service.ts
index f9a8f0d02..0cb52705a 100644
--- a/knox-token-management-ui/token-management/app/token.management.service.ts
+++ b/knox-token-management-ui/token-management/app/token.management.service.ts
@@ -38,6 +38,7 @@ export class TokenManagementService {
revokeKnoxTokenUrl = this.apiUrl + 'revoke';
revokeKnoxTokensBatchUrl = this.apiUrl + 'revokeTokens';
getTssStatusUrl = this.apiUrl + 'getTssStatus';
+ metadataInfoUrl = this.topologyContext + 'api/v1/metadata/info';
constructor(private http: HttpClient) {}
@@ -129,6 +130,25 @@ export class TokenManagementService {
});
}
+ isTokenHashKeyPresent(): Promise<boolean> {
+ let headers = new HttpHeaders();
+ headers = this.addJsonHeaders(headers);
+ return this.http.get(this.metadataInfoUrl, { headers: headers})
+ .toPromise()
+ .then(response => {
+ return response['generalProxyInfo']?.['enableTokenManagement']
=== 'true';
+ })
+ .catch((err: HttpErrorResponse) => {
+ console.debug('TokenManagementService -->
isTokenHashKeyPresent() --> '
+ + this.metadataInfoUrl + '\n error: ' + err.message);
+ if (err.status === 401) {
+ window.location.assign(document.location.pathname);
+ } else {
+ return this.handleError(err);
+ }
+ });
+ }
+
getSessionInformation(): Promise<SessionInformation> {
let headers = new HttpHeaders();
headers = this.addJsonHeaders(headers);