[DEV] Add and delete application token
This commit is contained in:
parent
7abf7f5674
commit
a2e1f5b24d
@ -52,7 +52,7 @@ public class ApplicationTokenResource {
|
|||||||
int nbRemoved = SqlWrapper.setDeleteWhere(ApplicationToken.class,
|
int nbRemoved = SqlWrapper.setDeleteWhere(ApplicationToken.class,
|
||||||
List.of(
|
List.of(
|
||||||
new WhereCondition("parentId", "=", applicationId),
|
new WhereCondition("parentId", "=", applicationId),
|
||||||
new WhereCondition("tokenId", "=", tokenId)
|
new WhereCondition("id", "=", tokenId)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (nbRemoved == 0) {
|
if (nbRemoved == 0) {
|
||||||
@ -79,7 +79,7 @@ public class ApplicationTokenResource {
|
|||||||
|
|
||||||
static String randomToken() {
|
static String randomToken() {
|
||||||
int len = 48;
|
int len = 48;
|
||||||
String valid_element = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789#_@-|[])('~$%*/\\.!?,";
|
String valid_element = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz0123456789#_@-~*!?";
|
||||||
// creating a StringBuffer size of AlphaNumericStr
|
// creating a StringBuffer size of AlphaNumericStr
|
||||||
StringBuilder out = new StringBuilder(len);
|
StringBuilder out = new StringBuilder(len);
|
||||||
int iii;
|
int iii;
|
||||||
@ -91,24 +91,24 @@ public class ApplicationTokenResource {
|
|||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
public record CreateRequest(String name, Integer validity) {};
|
||||||
@POST
|
@POST
|
||||||
@Path("/{applicationId}/create")
|
@Path("/{applicationId}/create")
|
||||||
@RolesAllowed("ADMIN")
|
@RolesAllowed("ADMIN")
|
||||||
public ApplicationToken createToken(
|
public ApplicationToken createToken(
|
||||||
@Context SecurityContext sc,
|
@Context SecurityContext sc,
|
||||||
@PathParam("applicationId") Long applicationId,
|
@PathParam("applicationId") Long applicationId,
|
||||||
@FormDataParam("name") String name,
|
CreateRequest request
|
||||||
@FormDataParam("validity") Integer validity
|
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
// correct input string stream :
|
// correct input string stream :
|
||||||
name = multipartCorrection(name);
|
String name = multipartCorrection(request.name());
|
||||||
//validity = multipartCorrection(validity);
|
//validity = multipartCorrection(validity);
|
||||||
System.out.println("create a nexw token...");
|
System.out.println("create a nexw token...");
|
||||||
if (applicationId == null) {
|
if (applicationId == null) {
|
||||||
throw new InputException("applicationId", "can not be null");
|
throw new InputException("applicationId", "can not be null");
|
||||||
}
|
}
|
||||||
int maximum = 365*5;
|
int maximum = 365*5;
|
||||||
|
Integer validity = request.validity();
|
||||||
if (validity == null || validity < 0 || validity > maximum) {
|
if (validity == null || validity < 0 || validity > maximum) {
|
||||||
validity = maximum;
|
validity = maximum;
|
||||||
}
|
}
|
||||||
@ -126,7 +126,10 @@ public class ApplicationTokenResource {
|
|||||||
// here we return the token to permit to the user to see it to set it in the application.
|
// here we return the token to permit to the user to see it to set it in the application.
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Cannot find a deserializer for non-concrete Map type [map type; class jakarta.ws.rs.core.MultivaluedMap, [simple type, class java.lang.String] -> [collection type; class java.util.List, contains [simple type, class java.lang.String]]]
|
||||||
|
at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
<table width="100%">
|
<table width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
<td width="25%"><b>id:</b></td>
|
<td width="25%"><b>id:</b></td>
|
||||||
<td width="75%">{{application.id}}</td>
|
<td width="75%">{{application?.id}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><b>Name:</b></td>
|
<td><b>Name:</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.name"
|
[value]="application?.name"
|
||||||
placeholder="Enter application name"
|
placeholder="Enter application name"
|
||||||
[hasError]="nameState !== true"
|
[hasError]="nameState !== true"
|
||||||
(changeValue)="checkName($event)"></app-entry>
|
(changeValue)="checkName($event)"></app-entry>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<td><b>Description:</b></td>
|
<td><b>Description:</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.description"
|
[value]="application?.description"
|
||||||
(changeValue)="updateDescription($event)"></app-entry>
|
(changeValue)="updateDescription($event)"></app-entry>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<td><b>Redirect (http://):</b></td>
|
<td><b>Redirect (http://):</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.redirect"
|
[value]="application?.redirect"
|
||||||
placeholder="Enter http redirect adresses "
|
placeholder="Enter http redirect adresses "
|
||||||
[hasError]="redirectState !== true"
|
[hasError]="redirectState !== true"
|
||||||
(changeValue)="checkRedirect($event)"></app-entry>
|
(changeValue)="checkRedirect($event)"></app-entry>
|
||||||
@ -44,7 +44,7 @@
|
|||||||
<td><b>Redirect development (http://):</b></td>
|
<td><b>Redirect development (http://):</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.redirectDev"
|
[value]="application?.redirectDev"
|
||||||
(changeValue)="updateRedirectDev($event)"></app-entry>
|
(changeValue)="updateRedirectDev($event)"></app-entry>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<td><b>Notification address (http://):</b></td>
|
<td><b>Notification address (http://):</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.notification"
|
[value]="application?.notification"
|
||||||
(changeValue)="updateNotification($event)"></app-entry>
|
(changeValue)="updateNotification($event)"></app-entry>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -60,7 +60,7 @@
|
|||||||
<td><b>TTL (seconds before expiration):</b></td>
|
<td><b>TTL (seconds before expiration):</b></td>
|
||||||
<td>
|
<td>
|
||||||
<app-entry
|
<app-entry
|
||||||
[value]="application.ttl"
|
[value]="application?.ttl"
|
||||||
(changeValue)="updateTTL($event)"></app-entry>
|
(changeValue)="updateTTL($event)"></app-entry>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -86,20 +86,37 @@
|
|||||||
<body>
|
<body>
|
||||||
<table class="table-model">
|
<table class="table-model">
|
||||||
<tr>
|
<tr>
|
||||||
<th width="5%">id</th>
|
<th>id</th>
|
||||||
<th width="25%">Name</th>
|
<th>Name</th>
|
||||||
<th width="30%">Expiration Time</th>
|
<th>Expiration Time</th>
|
||||||
<th width="40%">Token</th>
|
<th>Token</th>
|
||||||
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngFor="let token of tokens">
|
<tr *ngFor="let token of tokens">
|
||||||
<td>{{token.id}}</td>
|
<td>{{token.id}}</td>
|
||||||
<td>{{token.name}}</td>
|
<td>{{token.name}}</td>
|
||||||
<td>{{formatTimestamp(user.endValidityTime)}}</td>
|
<td>{{formatTimestamp(token.endValidityTime)}}</td>
|
||||||
<td>{{token.token}}</td>
|
<td>{{token.token}}</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="square-button login color-button-cancel color-shadow-black"
|
||||||
|
(click)="onRemoveApplicationToken($event, token)"
|
||||||
|
type="submit">
|
||||||
|
<i class="material-icons">delete_forever</i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
<footer>
|
<footer>
|
||||||
|
<app-entry
|
||||||
|
[value]="tokenName"
|
||||||
|
placeholder="Enter the token name / decription"
|
||||||
|
(changeValue)="checkTokenName($event)"></app-entry>
|
||||||
|
<app-entry
|
||||||
|
[value]="tokenTTL"
|
||||||
|
placeholder="Enter the Time To Lead"
|
||||||
|
(changeValue)="checkTokenTTL($event)"></app-entry>
|
||||||
<button
|
<button
|
||||||
class="button login color-button-validate color-shadow-black"
|
class="button login color-button-validate color-shadow-black"
|
||||||
id="create-button"
|
id="create-button"
|
||||||
@ -112,7 +129,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
|
||||||
<delete-confirm
|
<delete-confirm
|
||||||
[comment]="confirmDeleteComment"
|
[comment]="confirmDeleteComment"
|
||||||
(callback)="deleteConfirmed()"></delete-confirm>-->
|
(callback)="deleteConfirmed()"></delete-confirm>
|
@ -12,3 +12,21 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
|
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-model {
|
||||||
|
tr:nth-child(odd) {
|
||||||
|
background-color: rgb(180, 180, 180);
|
||||||
|
//color: #fff;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: darkgray;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
* @license PROPRIETARY (see license file)
|
* @license PROPRIETARY (see license file)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'app/service';
|
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'app/service';
|
||||||
import { ApplicationTokenModel } from 'app/service/application-token';
|
import { ApplicationTokenModel } from 'app/service/application-token';
|
||||||
import { AsyncActionState } from 'common/component';
|
import { AsyncActionState } from 'common/component';
|
||||||
|
import { NotificationService, PopInService } from 'common/service';
|
||||||
import { isNumeric } from 'common/utils';
|
import { isNumeric } from 'common/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -21,12 +22,15 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
id: number = undefined
|
id: number = undefined
|
||||||
application: ApplicationModel = undefined;
|
application: ApplicationModel = undefined;
|
||||||
applicationRef: ApplicationModel = undefined;
|
applicationRef: ApplicationModel = undefined;
|
||||||
tokens: any = undefined;
|
tokens: ApplicationTokenModel[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private applicationService: ApplicationService,
|
private applicationService: ApplicationService,
|
||||||
private applicationTokenService: ApplicationTokenService,
|
private applicationTokenService: ApplicationTokenService,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
|
private cdr: ChangeDetectorRef,
|
||||||
|
private popInService: PopInService,
|
||||||
|
private notificationService: NotificationService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -46,7 +50,7 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
});
|
});
|
||||||
this.applicationTokenService
|
this.applicationTokenService
|
||||||
.gets(this.id)
|
.gets(this.id)
|
||||||
.then((response: ApplicationTokenModel) => {
|
.then((response: ApplicationTokenModel[]) => {
|
||||||
console.log(`??? get full response: ${JSON.stringify(response, null, 4)}`);
|
console.log(`??? get full response: ${JSON.stringify(response, null, 4)}`);
|
||||||
self.tokens = response;
|
self.tokens = response;
|
||||||
})
|
})
|
||||||
@ -55,7 +59,9 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatTimestamp(unix_timestamp: number) {
|
||||||
|
return new Date(unix_timestamp).toISOString().replace("T", " ").replace("Z", " GMT").replace(".000", "");
|
||||||
|
}
|
||||||
|
|
||||||
updateDescription(newValue: string): void {
|
updateDescription(newValue: string): void {
|
||||||
this.application.description = newValue;
|
this.application.description = newValue;
|
||||||
@ -122,7 +128,7 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
*/
|
*/
|
||||||
checkName(newValue: string): void {
|
checkName(newValue: string): void {
|
||||||
this.application.name = newValue;
|
this.application.name = newValue;
|
||||||
if (this.application.name.length < 6) {
|
if (this.application?.name?.length < 6) {
|
||||||
this.nameState = "This name is too small >=6.";
|
this.nameState = "This name is too small >=6.";
|
||||||
}
|
}
|
||||||
this.nameState = true;
|
this.nameState = true;
|
||||||
@ -134,7 +140,7 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
checkRedirect(newValue: string): void {
|
checkRedirect(newValue: string): void {
|
||||||
this.application.redirect = newValue;
|
this.application.redirect = newValue;
|
||||||
this.redirectState = true;
|
this.redirectState = true;
|
||||||
if (this.application.redirect.length <= 5) {
|
if (this.application?.redirect?.length <= 5) {
|
||||||
this.redirectState = "This redirect is too small.";
|
this.redirectState = "This redirect is too small.";
|
||||||
}
|
}
|
||||||
this.updateButtonVisibility();
|
this.updateButtonVisibility();
|
||||||
@ -175,15 +181,59 @@ export class ApplicationEditScene implements OnInit {
|
|||||||
createToken(): void {
|
createToken(): void {
|
||||||
let self = this;
|
let self = this;
|
||||||
this.applicationTokenService
|
this.applicationTokenService
|
||||||
.create(this.id, "plpolp", 953)
|
.create(this.id, this.tokenName, this.tokenTTL)
|
||||||
.then((response: ApplicationTokenModel) => {
|
.then((response: ApplicationTokenModel) => {
|
||||||
console.log(`??? get full response: ${JSON.stringify(response, null, 4)}`);
|
console.log(`??? get fullllllll response: ${JSON.stringify(response, null, 4)}`);
|
||||||
self.tokens.append(response);
|
self.tokens.push(response);
|
||||||
|
self.cdr.detectChanges();
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((error: any) => {
|
||||||
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
|
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRemoveApplicationToken(_event: any, token: ApplicationTokenModel) {
|
||||||
|
this.confirmDeleteComment = `Delete the application token ID: [${this.application.id}/${token.id}] ${token.name}`;
|
||||||
|
this.confirmDeleteApplicationToken = token;
|
||||||
|
this.popInService.open('popin-delete-confirm');
|
||||||
|
}
|
||||||
|
|
||||||
|
removeApplicationConfirm(token: ApplicationTokenModel) {
|
||||||
|
let self = this;
|
||||||
|
this.applicationTokenService.remove(self.application.id, token.id)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
const index = self.tokens.indexOf(token, 0);
|
||||||
|
if (index > -1) {
|
||||||
|
self.tokens.splice(index, 1);
|
||||||
|
self.cdr.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).catch(
|
||||||
|
(error: any) => {
|
||||||
|
self.notificationService.errorRaw(`Fail to delete application token: [${self.application.id}/${token.id}] : ${token.name} ==> ${error}`)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
confirmDeleteComment: string = undefined;
|
||||||
|
confirmDeleteApplicationToken: ApplicationTokenModel = undefined;
|
||||||
|
|
||||||
|
deleteConfirmed() {
|
||||||
|
if(this.confirmDeleteApplicationToken !== undefined) {
|
||||||
|
this.removeApplicationConfirm(this.confirmDeleteApplicationToken);
|
||||||
|
this.confirmDeleteComment = undefined;
|
||||||
|
this.confirmDeleteApplicationToken = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokenName: string = undefined;
|
||||||
|
tokenTTL: number = undefined;
|
||||||
|
checkTokenName(newValue: string) {
|
||||||
|
this.tokenName = newValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
checkTokenTTL(newValue: string) {
|
||||||
|
if (isNumeric(newValue)) {
|
||||||
|
this.tokenTTL = Number(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ export class ApplicationTokenService {
|
|||||||
console.log('Start ApplicationTokenService');
|
console.log('Start ApplicationTokenService');
|
||||||
}
|
}
|
||||||
|
|
||||||
gets(applicationId: number): Promise<ApplicationTokenModel> {
|
gets(applicationId: number): Promise<ApplicationTokenModel[]> {
|
||||||
let self = this;
|
let self = this;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.http
|
this.http
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
[placeholder]="placeholder"
|
[placeholder]="placeholder"
|
||||||
required=""
|
required=""
|
||||||
[style.border]="hasError? '2px dashed red' : ''"
|
[style.border]="hasError? '2px dashed red' : ''"
|
||||||
[value]="value"
|
[value]="value===undefined?'':value"
|
||||||
(input)="onChangeValue($event.target.value)" />
|
(input)="onChangeValue($event.target.value)" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
* @license PROPRIETARY (see license file)
|
* @license PROPRIETARY (see license file)
|
||||||
*/
|
*/
|
||||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-entry',
|
selector: 'app-entry',
|
||||||
templateUrl: 'entry.html',
|
templateUrl: 'entry.html',
|
||||||
styleUrls: ['entry.less'],
|
styleUrls: ['entry.less'],
|
||||||
})
|
})
|
||||||
export class EntryComponent {
|
export class EntryComponent implements OnInit {
|
||||||
/// Value of the password
|
/// Value of the password
|
||||||
@Input() value: string = '';
|
@Input() value: string = '';
|
||||||
/// Placeholder of the Value
|
/// Placeholder of the Value
|
||||||
@ -20,6 +20,10 @@ export class EntryComponent {
|
|||||||
/// event when change the value of the password
|
/// event when change the value of the password
|
||||||
@Output() changeValue: EventEmitter<string> = new EventEmitter();
|
@Output() changeValue: EventEmitter<string> = new EventEmitter();
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
//if (value)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When input value change, need update the display and change the internal value.
|
* When input value change, need update the display and change the internal value.
|
||||||
* @param newValue New value set on the password
|
* @param newValue New value set on the password
|
||||||
|
Loading…
Reference in New Issue
Block a user