Skip to content

Commit 495dea2

Browse files
committed
Refresh instead of reload page
1 parent 07c1028 commit 495dea2

File tree

4 files changed

+344
-19
lines changed

4 files changed

+344
-19
lines changed

api/src/main/java/io/sentrius/sso/controllers/api/ZeroTrustATApiController.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,81 @@ public ResponseEntity<?> listZtatRequests(@RequestHeader("Authorization") String
327327
return ResponseEntity.ok(ztatTracker);
328328
}
329329

330+
@GetMapping("/list/{state}/{type}")
331+
@LimitAccess(ztatAccess = {ZeroTrustAccessTokenEnum.CAN_VIEW_ZTATS})
332+
public ResponseEntity<?> listTypedZtatRequests(@RequestHeader("Authorization") String token,
333+
@PathVariable("type") String type,
334+
@PathVariable("state") String state,
335+
HttpServletRequest request, HttpServletResponse response) {
336+
String compactJwt = token.startsWith("Bearer ") ? token.substring(7) : token;
337+
338+
339+
log.info("Received ZTAT request from agent: {}", compactJwt);
340+
if (!keycloakService.validateJwt(compactJwt)) {
341+
log.warn("Invalid Keycloak token");
342+
return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED).body("Invalid Keycloak token");
343+
}
344+
345+
// Extract agent identity from the JWT
346+
var operatingUser = getOperatingUser(request, response );
347+
348+
// Extract agent identity from the JWT
349+
String agentId = keycloakService.extractAgentId(compactJwt);
350+
351+
if (null == operatingUser) {
352+
log.warn("No operating user found for agent: {}", agentId);
353+
var username = keycloakService.extractUsername(compactJwt);
354+
operatingUser = userService.getUserByUsername(username);
355+
356+
}
357+
List<ZtatDTO> ztatTracker = new ArrayList<ZtatDTO>();
358+
switch(type){
359+
case "terminal":
360+
if ("denied".equalsIgnoreCase(state)) {
361+
ztatTracker = ztatService.getDeniedJITRequests(operatingUser);
362+
} else if ("approved".equalsIgnoreCase(state)) {
363+
ztatTracker = ztatService.getApprovedJITRequests(operatingUser);
364+
} else {
365+
ztatTracker = ztatService.getOpenJITRequests(operatingUser);
366+
}
367+
break;
368+
case "ops":
369+
if ("denied".equalsIgnoreCase(state)) {
370+
ztatTracker = ztatService.getDeniedOpsJITRequests(operatingUser);
371+
} else if ("approved".equalsIgnoreCase(state)) {
372+
ztatTracker = ztatService.getApprovedOpsJITRequests(operatingUser);
373+
} else {
374+
ztatTracker = ztatService.getOpenOpsRequests(operatingUser);
375+
}
376+
break;
377+
case "atat":
378+
if ("denied".equalsIgnoreCase(state)) {
379+
ztatTracker = ztatService.getDeniedOpsJITRequests(operatingUser);
380+
} else if ("approved".equalsIgnoreCase(state)) {
381+
ztatTracker = ztatService.getApprovedOpsJITRequests(operatingUser);
382+
} else {
383+
ztatTracker = ztatService.getOpenOpsRequests(operatingUser);
384+
}
385+
ztatTracker = ztatTracker.stream().filter(dto -> {
386+
if (dto.getCommand().equals("register")) {
387+
return false;
388+
}
389+
try {
390+
if (userService.isNPE(dto.getUserName())){
391+
return true;
392+
}
393+
} catch (Exception e) {
394+
throw new RuntimeException(e);
395+
}
396+
return false;
397+
}).toList();
398+
break;
399+
default:
400+
log.warn("Invalid type: {}", type);
401+
}
402+
return ResponseEntity.ok(ztatTracker);
403+
}
404+
330405
@PostMapping("/jwt/issue")
331406
public ResponseEntity<UserTokenResponse> issueZtat(@RequestBody UserTokenDTO request) {
332407
String ztat = tokenService.issueZtat(request.getUserId(), request.getSessionId(), request.getPublicKey());

api/src/main/resources/templates/sso/ztats/view_ztats.html

Lines changed: 248 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -254,39 +254,272 @@ <h2 class="toast-header">Trust AT (TAT) Management</h2>
254254

255255
<!-- DataTables Initialization -->
256256
<script>
257-
$(document).ready(function () {
258-
$('#open-terminal-table, #open-ops-table, #approved-terminal-table, #approved-ops-table, #denied-terminal-table, #denied-ops-table').DataTable();
257+
function reloadTerminalTATs() {
258+
$.get('/api/v1/zerotrust/accesstoken/list/terminal', function (data) {
259+
const $table = $('#open-terminal-table').DataTable();
260+
$table.clear();
261+
262+
for (let s of data) {
263+
let actions = '';
264+
if (s.canApprove) {
265+
actions += `<button id="app_btn_${s.id}" class="btn-secondary app_btn">Approve</button>`;
266+
}
267+
if (s.canDeny) {
268+
actions += `<button id="den_btn_${s.id}" class="btn-secondary den_btn">Deny</button>`;
269+
}
270+
if (s.isCurrentUser) {
271+
actions += `<button id="rev_btn_${s.id}" class="btn-secondary rev_btn">Revoke</button>`;
272+
}
273+
274+
$table.row.add([
275+
s.command,
276+
s.userName,
277+
s.hostName,
278+
actions
279+
]);
280+
}
281+
282+
$table.draw();
283+
attachZtatButtonHandlers(); // re-bind the click events
284+
});
285+
286+
$.get('/api/v1/zerotrust/accesstoken/list/approved/terminal', function (data) {
287+
const $table = $('#approved-terminal-table').DataTable();
288+
$table.clear();
289+
290+
for (let s of data) {
291+
let actions = '';
292+
if (s.canApprove) {
293+
actions += `<button id="app_btn_${s.id}" class="btn-secondary app_btn">Approve</button>`;
294+
}
295+
if (s.canDeny) {
296+
actions += `<button id="den_btn_${s.id}" class="btn-secondary den_btn">Deny</button>`;
297+
}
298+
if (s.isCurrentUser) {
299+
actions += `<button id="rev_btn_${s.id}" class="btn-secondary rev_btn">Revoke</button>`;
300+
}
301+
302+
$table.row.add([
303+
s.command,
304+
s.userName,
305+
s.hostName,
306+
s.usesRemaining,
307+
actions
308+
]);
309+
}
310+
311+
$table.draw();
312+
attachZtatButtonHandlers(); // re-bind the click events
313+
});
314+
315+
$.get('/api/v1/zerotrust/accesstoken/list/denied/terminal', function (data) {
316+
const $table = $('#denied-terminal-table').DataTable();
317+
$table.clear();
318+
319+
for (let s of data) {
320+
let actions = '';
321+
if (s.canApprove) {
322+
actions += `<button id="app_btn_${s.id}" class="btn-secondary app_btn">Approve</button>`;
323+
}
324+
if (s.canDeny) {
325+
actions += `<button id="den_btn_${s.id}" class="btn-secondary den_btn">Deny</button>`;
326+
}
327+
328+
$table.row.add([
329+
s.command,
330+
s.userName,
331+
s.hostName,
332+
actions
333+
]);
334+
}
335+
336+
$table.draw();
337+
attachZtatButtonHandlers(); // re-bind the click events
338+
});
339+
}
340+
341+
function reloadOpsTATs() {
342+
$.get('/api/v1/zerotrust/accesstoken/list/ops', function (data) {
343+
const $table = $('#open-ops-table').DataTable();
344+
$table.clear();
345+
346+
for (let s of data) {
347+
let actions = '';
348+
if (s.canApprove) {
349+
actions += `<button id="ops_app_btn_${s.id}" class="btn-secondary ops_app_btn">Approve</button>`;
350+
}
351+
if (s.canDeny) {
352+
actions += `<button id="ops_den_btn_${s.id}" class="btn-secondary ops_den_btn">Deny</button>`;
353+
}
354+
if (s.isCurrentUser) {
355+
actions += `<button id="ops_rev_btn_${s.id}" class="btn-secondary ops_rev_btn">Revoke</button>`;
356+
}
357+
358+
$table.row.add([
359+
s.summary,
360+
s.userName,
361+
actions
362+
]);
363+
}
364+
365+
$table.draw();
366+
attachZtatButtonHandlers(); // re-bind the click events
367+
});
259368

260-
$(".app_btn").click(function () {
369+
$.get('/api/v1/zerotrust/accesstoken/list/approved/ops', function (data) {
370+
const $table = $('#approved-ops-table').DataTable();
371+
$table.clear();
372+
373+
for (let s of data) {
374+
let actions = '';
375+
if (s.canApprove) {
376+
actions += `<button id="ops_app_btn_${s.id}" class="btn-secondary ops_app_btn">Approve</button>`;
377+
}
378+
if (s.canDeny) {
379+
actions += `<button id="ops_den_btn_${s.id}" class="btn-secondary ops_den_btn">Deny</button>`;
380+
}
381+
if (s.isCurrentUser) {
382+
actions += `<button id="ops_rev_btn_${s.id}" class="btn-secondary ops_rev_btn">Revoke</button>`;
383+
}
384+
385+
$table.row.add([
386+
s.summary,
387+
s.userName,
388+
s.usesRemaining
389+
]);
390+
}
391+
392+
$table.draw();
393+
attachZtatButtonHandlers(); // re-bind the click events
394+
});
395+
396+
$.get('/api/v1/zerotrust/accesstoken/list/denied/ops', function (data) {
397+
const $table = $('#denied-ops-table').DataTable();
398+
$table.clear();
399+
400+
for (let s of data) {
401+
let actions = '';
402+
if (s.canApprove) {
403+
actions += `<button id="ops_app_btn_${s.id}" class="btn-secondary ops_app_btn">Approve</button>`;
404+
}
405+
if (s.canDeny) {
406+
actions += `<button id="ops_den_btn_${s.id}" class="btn-secondary ops_den_btn">Deny</button>`;
407+
}
408+
409+
$table.row.add([
410+
s.summary,
411+
s.userName,
412+
actions
413+
]);
414+
}
415+
416+
$table.draw();
417+
attachZtatButtonHandlers(); // re-bind the click events
418+
});
419+
}
420+
421+
422+
function attachZtatButtonHandlers() {
423+
$(".app_btn").off().click(function () {
261424
let id = this.id.split("_").pop();
262-
$.get('/api/v1/zerotrust/accesstoken/terminal/approve?ztatId=' + id, {}, function() {
263-
location.reload(); });
425+
$.get('/api/v1/zerotrust/accesstoken/terminal/approve?ztatId=' + id, {}, function () {
426+
reloadTerminalTATs();
427+
});
264428
});
265429

266-
$(".den_btn").click(function () {
430+
$(".den_btn").off().click(function () {
267431
let id = this.id.split("_").pop();
268-
$.get('/api/v1/zerotrust/accesstoken/terminal/deny?ztatId='+ id, {}, function() { location.reload(); });
432+
$.get('/api/v1/zerotrust/accesstoken/terminal/deny?ztatId=' + id, {}, function () {
433+
reloadTerminalTATs();
434+
});
269435
});
270436

271-
$(".rev_btn").click(function () {
437+
$(".rev_btn").off().click(function () {
272438
let id = this.id.split("_").pop();
273-
$.get('/api/v1/zerotrust/accesstoken/terminal/revoke?ztatId='+ id, {}, function() { location.reload(); });
439+
$.get('/api/v1/zerotrust/accesstoken/terminal/revoke?ztatId=' + id, {}, function () {
440+
reloadTerminalTATs();
441+
});
274442
});
275443

276-
$(".ops_app_btn").click(function () {
444+
$(".ops_app_btn").off().click(function () {
277445
let id = this.id.split("_").pop();
278-
$.get('/api/v1/zerotrust/accesstoken/ops/approve?ztatId='+ id, {}, function() { location.reload(); });
446+
$.get('/api/v1/zerotrust/accesstoken/ops/approve?ztatId=' + id, {}, function () {
447+
reloadOpsTATs();
448+
});
279449
});
280450

281-
$(".ops_den_btn").click(function () {
451+
$(".ops_den_btn").off().click(function () {
282452
let id = this.id.split("_").pop();
283-
$.get('/api/v1/zerotrust/accesstoken/ops/deny?ztatId='+ id, {}, function() { location.reload(); });
453+
$.get('/api/v1/zerotrust/accesstoken/ops/deny?ztatId=' + id, {}, function () {
454+
reloadOpsTATs();
455+
});
284456
});
285457

286-
$(".ops_rev_btn").click(function () {
458+
$(".ops_rev_btn").off().click(function () {
287459
let id = this.id.split("_").pop();
288-
$.get('/api/v1/zerotrust/accesstoken/my/ops/revoke?ztatId='+ id, {}, function() { location.reload(); });
460+
$.get('/api/v1/zerotrust/accesstoken/my/ops/revoke?ztatId=' + id, {}, function () {
461+
reloadOpsTATs();
462+
});
289463
});
464+
}
465+
466+
let openTerminalTable, openOpsTable, approvedTerminalTable, approvedOpsTable, deniedTerminalTable, deniedOpsTable;
467+
468+
$(document).ready(function () {
469+
openTerminalTable = $('#open-terminal-table').DataTable({
470+
columns: [
471+
{ title: "Operation" },
472+
{ title: "User" },
473+
{ title: "System" },
474+
{ title: "Actions" }
475+
]
476+
});
477+
478+
openOpsTable = $('#open-ops-table').DataTable({
479+
columns: [
480+
{ title: "Operation" },
481+
{ title: "User" },
482+
{ title: "Actions" }
483+
]
484+
});
485+
486+
approvedTerminalTable = $('#approved-terminal-table').DataTable({
487+
columns: [
488+
{ title: "Operation" },
489+
{ title: "User" },
490+
{ title: "System" },
491+
{ title: "Uses Remaining" },
492+
{ title: "Actions" }
493+
]
494+
});
495+
496+
approvedOpsTable = $('#approved-ops-table').DataTable({
497+
columns: [
498+
{ title: "Operation" },
499+
{ title: "User" },
500+
{ title: "Uses Remaining" },
501+
{ title: "Actions" }
502+
]
503+
});
504+
505+
deniedTerminalTable = $('#denied-terminal-table').DataTable({
506+
columns: [
507+
{ title: "Operation" },
508+
{ title: "User" },
509+
{ title: "System" },
510+
{ title: "Actions" }
511+
]
512+
});
513+
514+
deniedOpsTable = $('#denied-ops-table').DataTable({
515+
columns: [
516+
{ title: "Operation" },
517+
{ title: "User" },
518+
{ title: "Actions" }
519+
]
520+
});
521+
522+
attachZtatButtonHandlers();
290523
});
291524
</script>
292525

dataplane/src/main/java/io/sentrius/sso/core/services/security/ZeroTrustAccessTokenService.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,25 @@ public boolean hasJITRequest(String command, User user, HostSystem system) {
277277
return ztatRequestService.hasJITRequest(command, user.getId(), system.getId());
278278
}
279279

280-
public List<ZtatDTO> getOpenJITRequests(User operatingUser) {
281-
return ztatRequestService.getOpenAccessTokenRequests(operatingUser);
282-
}
280+
public List<ZtatDTO> getOpenJITRequests(User operatingUser) {
281+
return ztatRequestService.getOpenAccessTokenRequests(operatingUser);
282+
}
283283

284+
public List<ZtatDTO> getDeniedJITRequests(User operatingUser) {
285+
return ztatRequestService.getDeniedTerminalAccessTokenRequests(operatingUser);
286+
}
287+
288+
public List<ZtatDTO> getDeniedOpsJITRequests(User operatingUser) {
289+
return ztatRequestService.getDeniedOpsAccessTokenRequests(operatingUser);
290+
}
291+
292+
public List<ZtatDTO> getApprovedJITRequests(User operatingUser) {
293+
return ztatRequestService.getApprovedTerminalAccessTokenRequests(operatingUser);
294+
}
295+
296+
public List<ZtatDTO> getApprovedOpsJITRequests(User operatingUser) {
297+
return ztatRequestService.getApprovedOpsAccessTokenRequests(operatingUser);
298+
}
284299
public List<ZtatDTO> getOpenOpsRequests(User operatingUser) {
285300
return ztatRequestService.getOpenOpsRequests(operatingUser);
286301
}

0 commit comments

Comments
 (0)