blob: 4eb70308936ef8124fa55a1e426944bfe5809c0b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 { HttpClient} from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import Swal from 'sweetalert2';
import { TokenResultData, TssStatusData } from './token-generation.models';
import { TokenGenService } from './token-generation.service';
@Component({
selector: 'app-token-generation',
templateUrl: './token-generation.component.html',
providers: []
})
export class TokenGenerationComponent implements OnInit {
tssStatusMessageLevel: 'info' | 'warning' | 'error';
tssStatusMessage: string;
requestErrorMessage: string;
hasResult: boolean;
// Data coming from the form
tokenGenFrom = new FormGroup({
comment : new FormControl('', Validators.maxLength(255)),
lifespanDays : new FormControl(0, [
Validators.min(0),
Validators.max(3650),
Validators.required,
Validators.pattern('^[0-9]*$')
]),
lifespanHours : new FormControl(1, [
Validators.min(0),
Validators.max(23),
Validators.required,
Validators.pattern('^[0-9]*$')
]),
lifespanMins : new FormControl(0, [
Validators.min(0),
Validators.max(59),
Validators.required,
Validators.pattern('^[0-9]*$')
]),
impersonation : new FormControl('', Validators.maxLength(255))
}, this.allZeroValidator());
get comment() { return this.tokenGenFrom.get('comment'); }
get lifespanDays() { return this.tokenGenFrom.get('lifespanDays'); }
get lifespanHours() { return this.tokenGenFrom.get('lifespanHours'); }
get lifespanMins() { return this.tokenGenFrom.get('lifespanMins'); }
get impersonation() { return this.tokenGenFrom.get('impersonation'); }
// Data coming from Token generating request
tokenResultData: TokenResultData;
// Data coming from TokenStateService status request
tssStatus: TssStatusData;
constructor(private http: HttpClient, private tokenGenService: TokenGenService) {
this.tssStatusMessageLevel = 'info';
this.tssStatusMessage = '';
this.requestErrorMessage = '';
this.hasResult = false;
this.tssStatus = new TssStatusData();
this.tokenResultData = new TokenResultData();
}
ngOnInit(): void {
this.tokenGenService.isTokenHashKeyPresent().then(
tokenHashKeyPresent => {
if (tokenHashKeyPresent) {
this.setTokenStateServiceStatus();
} else {
this.showMissingKnoxTokenHashKeyPopup();
}
});
}
generateToken() {
if (this.tokenGenFrom.valid && this.tssStatus.tokenManagementEnabled && this.tssStatus.allowedTssForTokengen) {
if (this.isMaximumLifetimeExceeded()) {
Swal.fire(
{
title: 'Warning',
text: `You are trying to generate a token with a lifetime that exceeds the configured maximum.
In this case the generated token's lifetime will be limited to the configured maximum.`,
icon: 'warning',
reverseButtons: true,
confirmButtonText: 'Generate token anyway',
confirmButtonColor: '#e64942',
showCancelButton: true,
cancelButtonText: '<span style="color: #555;">Adjust request lifetime</span>',
cancelButtonColor: '#efefef'
}).then((willGenerateToken) => {
if (willGenerateToken.isConfirmed) {
this.requestToken();
}
});
} else {
this.requestToken();
}
}
}
setTokenStateServiceStatus() {
this.tokenGenService.getTokenStateServiceStatus()
.then(tssStatus => {
this.tssStatus = tssStatus;
this.decideTssMessage();
})
.catch((errorMessage) => {
this.requestErrorMessage = errorMessage;
});
}
copyTextToClipboard(elementId) {
let toBeCopied = document.getElementById(elementId).innerText.trim();
const tempTextArea = document.createElement('textarea');
tempTextArea.value = toBeCopied;
document.body.appendChild(tempTextArea);
tempTextArea.select();
document.execCommand('copy');
document.body.removeChild(tempTextArea);
Swal.fire({
text: 'Copied to clipboard!',
timer: 1000,
showConfirmButton: false,
});
}
private requestToken() {
this.requestErrorMessage = '';
this.hasResult = false;
let params = {
lifespanInputEnabled: this.tssStatus.lifespanInputEnabled,
comment: this.comment.value,
impersonation: this.impersonation.value,
lifespanDays: this.lifespanDays.value,
lifespanHours: this.lifespanHours.value,
lifespanMins: this.lifespanMins.value
};
this.tokenGenService.getGeneratedTokenData(params)
.then(tokenResultData => {
this.hasResult = true;
this.tokenResultData = tokenResultData;
})
.catch((errorMessage) => {
this.requestErrorMessage = errorMessage;
});
}
private allZeroValidator(): ValidatorFn {
return (formGroup: FormGroup) => {
if (
formGroup.get('lifespanDays').value === 0 &&
formGroup.get('lifespanHours').value === 0 &&
formGroup.get('lifespanMins').value === 0
) {
return {allZero: true};
}
return null;
};
}
private isMaximumLifetimeExceeded() {
if (this.tssStatus.maximumLifetimeSeconds === -1) {
return false;
}
if (!this.tssStatus.lifespanInputEnabled) {
return false;
}
let daysInSeconds = this.lifespanDays.value * 86400;
let hoursInSeconds = this.lifespanHours.value * 3600;
let minsInSeconds = this.lifespanMins.value * 60;
let suppliedLifetime = daysInSeconds + hoursInSeconds + minsInSeconds;
return suppliedLifetime > this.tssStatus.maximumLifetimeSeconds;
}
private decideTssMessage() {
if (this.tssStatus.tokenManagementEnabled) {
if (this.tssStatus.allowedTssForTokengen) {
if (this.tssStatus.actualTssBackend === 'DerbyDBTokenStateService') {
this.setTssMessage('warning', `Token management backend is configured to store tokens in a Derby DB on local file system.
This is only valid in non-HA environments!`);
} else {
this.setTssMessage('info', 'Token management backend is properly configured for HA and production deployments.');
}
} else {
this.setTssMessage('error', 'Token management backend initialization failed, token generation disabled.');
}
} else {
this.setTssMessage('error', 'Token management is disabled');
}
}
private setTssMessage(level: 'info' | 'warning' | 'error', message: string) {
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'
});
}
}