From 282bbba3aaa6ff3410db3675a3a36be126c369bc Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 23 Oct 2020 14:36:10 +0200 Subject: [PATCH] [New] Requiring TX for privilege services --- .../endpoint/PrivilegePoliciesService.java | 32 ++++++--- .../rest/endpoint/PrivilegeRolesService.java | 34 +++++++--- .../rest/endpoint/PrivilegeUsersService.java | 68 ++++++++++++------- .../rest/endpoint/UserSessionsService.java | 51 ++++++++++---- ...egeAddOrReplacePrivilegeOnRoleService.java | 8 ++- .../roles/PrivilegeAddRoleService.java | 8 ++- ...ivilegeRemovePrivilegeFromRoleService.java | 8 ++- .../roles/PrivilegeRemoveRoleService.java | 8 ++- .../roles/PrivilegeUpdateRoleService.java | 8 ++- .../users/PrivilegeAddRoleToUserService.java | 8 ++- .../PrivilegeRemoveRoleFromUserService.java | 8 ++- .../users/PrivilegeRemoveUserService.java | 8 ++- .../users/PrivilegeSetUserLocaleService.java | 18 ++--- .../PrivilegeSetUserPasswordService.java | 23 ++++--- .../users/PrivilegeSetUserStateService.java | 18 ++--- .../PrivilegeUpdateUserRolesService.java | 37 +++++----- .../users/PrivilegeUpdateUserService.java | 8 ++- 17 files changed, 213 insertions(+), 140 deletions(-) diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegePoliciesService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegePoliciesService.java index 2c9511366..d59d09f5d 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegePoliciesService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegePoliciesService.java @@ -1,12 +1,12 @@ /* * Copyright 2015 Robert von Burg - * + * * Licensed 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. @@ -15,6 +15,9 @@ */ package li.strolch.rest.endpoint; +import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_ACTION; +import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_ACTION_GET_POLICIES; + import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -26,8 +29,10 @@ import java.util.Map; import com.google.gson.JsonObject; import li.strolch.agent.api.ComponentContainer; +import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.model.Certificate; +import li.strolch.privilege.model.SimpleRestrictable; import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchRestfulConstants; @@ -44,18 +49,27 @@ public class PrivilegePoliciesService { return container.getPrivilegeHandler().getPrivilegeHandler(); } + private static String getContext() { + StackTraceElement element = new Throwable().getStackTrace()[2]; + return element.getClassName() + "." + element.getMethodName(); + } + @GET @Produces(MediaType.APPLICATION_JSON) - public Response getRoles(@Context HttpServletRequest request) { + public Response getPrivilegePolicies(@Context HttpServletRequest request) { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - Map policyDefs = privilegeHandler.getPolicyDefs(cert); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.validateAction(new SimpleRestrictable(PRIVILEGE_ACTION, PRIVILEGE_ACTION_GET_POLICIES)); - JsonObject policiesJ = new JsonObject(); - for (String key : policyDefs.keySet()) { - policiesJ.addProperty(key, policyDefs.get(key)); + Map policyDefs = privilegeHandler.getPolicyDefs(cert); + + JsonObject policiesJ = new JsonObject(); + for (String key : policyDefs.keySet()) { + policiesJ.addProperty(key, policyDefs.get(key)); + } + return Response.ok(policiesJ.toString(), MediaType.APPLICATION_JSON).build(); } - return Response.ok(policiesJ.toString(), MediaType.APPLICATION_JSON).build(); } } diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeRolesService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeRolesService.java index affa242b3..e9b6d76b0 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeRolesService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeRolesService.java @@ -16,6 +16,7 @@ package li.strolch.rest.endpoint; import static java.util.Comparator.comparing; +import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_ROLE; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; @@ -27,6 +28,7 @@ import com.google.gson.JsonArray; import li.strolch.agent.api.ComponentContainer; import li.strolch.model.json.PrivilegeElementFromJsonVisitor; import li.strolch.model.json.PrivilegeElementToJsonVisitor; +import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.PrivilegeRep; @@ -48,20 +50,29 @@ public class PrivilegeRolesService { return container.getPrivilegeHandler().getPrivilegeHandler(); } + private static String getContext() { + StackTraceElement element = new Throwable().getStackTrace()[2]; + return element.getClassName() + "." + element.getMethodName(); + } + @GET @Produces(MediaType.APPLICATION_JSON) public Response getRoles(@Context HttpServletRequest request) { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); - JsonArray rolesJ = privilegeHandler.getRoles(cert).stream() // - .sorted(comparing(roleRep -> roleRep.getName().toLowerCase())) // - .collect(JsonArray::new, // - (array, role) -> array.add(role.accept(visitor)), // - JsonArray::addAll); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_ROLE); - return Response.ok(rolesJ.toString(), MediaType.APPLICATION_JSON).build(); + PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); + JsonArray rolesJ = privilegeHandler.getRoles(cert).stream() // + .sorted(comparing(roleRep -> roleRep.getName().toLowerCase())) // + .collect(JsonArray::new, // + (array, role) -> array.add(role.accept(visitor)), // + JsonArray::addAll); + + return Response.ok(rolesJ.toString(), MediaType.APPLICATION_JSON).build(); + } } @GET @@ -71,9 +82,12 @@ public class PrivilegeRolesService { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - RoleRep role = privilegeHandler.getRole(cert, rolename); - return Response.ok(role.accept(new PrivilegeElementToJsonVisitor()).toString(), MediaType.APPLICATION_JSON) - .build(); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_ROLE); + + RoleRep role = privilegeHandler.getRole(cert, rolename); + return Response.ok(role.accept(new PrivilegeElementToJsonVisitor()).toString(), MediaType.APPLICATION_JSON).build(); + } } @POST diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeUsersService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeUsersService.java index 55fb0127f..fa10c7f98 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeUsersService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/PrivilegeUsersService.java @@ -16,6 +16,7 @@ package li.strolch.rest.endpoint; import static java.util.Comparator.comparing; +import static li.strolch.privilege.handler.PrivilegeHandler.PRIVILEGE_GET_USER; import static li.strolch.rest.helper.RestfulHelper.toJson; import static li.strolch.search.SearchBuilder.buildSimpleValueSearch; @@ -34,6 +35,7 @@ import com.google.gson.*; import li.strolch.agent.api.ComponentContainer; import li.strolch.model.json.PrivilegeElementFromJsonVisitor; import li.strolch.model.json.PrivilegeElementToJsonVisitor; +import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.handler.PrivilegeHandler; import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.UserRep; @@ -65,27 +67,36 @@ public class PrivilegeUsersService { return container.getPrivilegeHandler().getPrivilegeHandler(); } + private static String getContext() { + StackTraceElement element = new Throwable().getStackTrace()[2]; + return element.getClassName() + "." + element.getMethodName(); + } + @GET @Produces(MediaType.APPLICATION_JSON) public Response queryUsers(@Context HttpServletRequest request, @BeanParam QueryData queryData) { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - String query = queryData.getQuery(); - List users = privilegeHandler.getUsers(cert); - SearchResult result = buildSimpleValueSearch(new ValueSearch(), query, Arrays.asList( // - UserRep::getUsername, // - UserRep::getFirstname, // - UserRep::getLastname, // - userRep -> userRep.getUserState().name(), // - UserRep::getRoles)) // - .search(users) // - .orderBy(comparing(r -> r.getUsername().toLowerCase())); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_USER); - PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); - JsonObject root = toJson(queryData, users.size(), result, t -> t.accept(visitor)); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - return Response.ok(gson.toJson(root), MediaType.APPLICATION_JSON).build(); + String query = queryData.getQuery(); + List users = privilegeHandler.getUsers(cert); + SearchResult result = buildSimpleValueSearch(new ValueSearch(), query, Arrays.asList( // + UserRep::getUsername, // + UserRep::getFirstname, // + UserRep::getLastname, // + userRep -> userRep.getUserState().name(), // + UserRep::getRoles)) // + .search(users) // + .orderBy(comparing(r -> r.getUsername().toLowerCase())); + + PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); + JsonObject root = toJson(queryData, users.size(), result, t -> t.accept(visitor)); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + return Response.ok(gson.toJson(root), MediaType.APPLICATION_JSON).build(); + } } @POST @@ -96,16 +107,20 @@ public class PrivilegeUsersService { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_USER); - UserRep queryRep = new PrivilegeElementFromJsonVisitor().userRepFromJson(query); - JsonArray usersArr = privilegeHandler.queryUsers(cert, queryRep).stream() // - .sorted(comparing(r -> r.getUsername().toLowerCase())) // - .collect(JsonArray::new, // - (array, user) -> array.add(user.accept(visitor)), // - JsonArray::addAll); + PrivilegeElementToJsonVisitor visitor = new PrivilegeElementToJsonVisitor(); - return Response.ok(usersArr.toString(), MediaType.APPLICATION_JSON).build(); + UserRep queryRep = new PrivilegeElementFromJsonVisitor().userRepFromJson(query); + JsonArray usersArr = privilegeHandler.queryUsers(cert, queryRep).stream() // + .sorted(comparing(r -> r.getUsername().toLowerCase())) // + .collect(JsonArray::new, // + (array, user) -> array.add(user.accept(visitor)), // + JsonArray::addAll); + + return Response.ok(usersArr.toString(), MediaType.APPLICATION_JSON).build(); + } } @GET @@ -115,9 +130,12 @@ public class PrivilegeUsersService { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); PrivilegeHandler privilegeHandler = getPrivilegeHandler(); - UserRep user = privilegeHandler.getUser(cert, username); - return Response.ok(user.accept(new PrivilegeElementToJsonVisitor()).toString(), MediaType.APPLICATION_JSON) - .build(); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_USER); + + UserRep user = privilegeHandler.getUser(cert, username); + return Response.ok(user.accept(new PrivilegeElementToJsonVisitor()).toString(), MediaType.APPLICATION_JSON).build(); + } } @POST diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java index 474b5a8e4..8c9e5e2c1 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/endpoint/UserSessionsService.java @@ -16,6 +16,7 @@ package li.strolch.rest.endpoint; import static li.strolch.rest.helper.RestfulHelper.toJson; +import static li.strolch.runtime.StrolchConstants.StrolchPrivilegeConstants.PRIVILEGE_GET_SESSION; import static li.strolch.search.SearchBuilder.buildSimpleValueSearch; import javax.servlet.http.HttpServletRequest; @@ -31,6 +32,7 @@ import java.util.Locale; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; +import li.strolch.persistence.api.StrolchTransaction; import li.strolch.privilege.model.Certificate; import li.strolch.rest.RestfulStrolchComponent; import li.strolch.rest.StrolchRestfulConstants; @@ -48,6 +50,11 @@ public class UserSessionsService { private static final Logger logger = LoggerFactory.getLogger(UserSessionsService.class); + private static String getContext() { + StackTraceElement element = new Throwable().getStackTrace()[2]; + return element.getClassName() + "." + element.getMethodName(); + } + @GET @Produces(MediaType.APPLICATION_JSON) public Response querySessions(@Context HttpServletRequest request, @BeanParam QueryData queryData) { @@ -56,19 +63,23 @@ public class UserSessionsService { logger.info("[" + cert.getUsername() + "] Querying user sessions..."); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); - String query = queryData.getQuery(); - List sessions = sessionHandler.getSessions(cert, source); + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_SESSION); - SearchResult result = buildSimpleValueSearch(new ValueSearch(), query, - Arrays.asList( // - UserSession::getUsername, // - UserSession::getFirstname, // - UserSession::getLastname, // - UserSession::getUserRoles)).search(sessions); + String query = queryData.getQuery(); + List sessions = sessionHandler.getSessions(cert, source); - JsonObject root = toJson(queryData, sessions.size(), result, UserSession::toJson); - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - return Response.ok(gson.toJson(root), MediaType.APPLICATION_JSON).build(); + SearchResult result = buildSimpleValueSearch(new ValueSearch(), query, + Arrays.asList( // + UserSession::getUsername, // + UserSession::getFirstname, // + UserSession::getLastname, // + UserSession::getUserRoles)).search(sessions); + + JsonObject root = toJson(queryData, sessions.size(), result, UserSession::toJson); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + return Response.ok(gson.toJson(root), MediaType.APPLICATION_JSON).build(); + } } @GET @@ -79,8 +90,13 @@ public class UserSessionsService { String source = (String) request.getAttribute(StrolchRestfulConstants.STROLCH_REQUEST_SOURCE); logger.info("[" + cert.getUsername() + "] Returning session " + sessionId); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); - UserSession session = sessionHandler.getSession(cert, source, sessionId); - return Response.ok(session.toJson().toString(), MediaType.APPLICATION_JSON).build(); + + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_SESSION); + + UserSession session = sessionHandler.getSession(cert, source, sessionId); + return Response.ok(session.toJson().toString(), MediaType.APPLICATION_JSON).build(); + } } @DELETE @@ -90,8 +106,13 @@ public class UserSessionsService { Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); logger.info("[" + cert.getUsername() + "] Invalidating session " + sessionId); StrolchSessionHandler sessionHandler = RestfulStrolchComponent.getInstance().getSessionHandler(); - sessionHandler.invalidate(cert, sessionId); - return ResponseUtil.toResponse(); + + try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getContext())) { + tx.getPrivilegeContext().assertHasPrivilege(PRIVILEGE_GET_SESSION); + + sessionHandler.invalidate(cert, sessionId); + return ResponseUtil.toResponse(); + } } @PUT diff --git a/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddOrReplacePrivilegeOnRoleService.java b/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddOrReplacePrivilegeOnRoleService.java index 9e51debd2..6806a8987 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddOrReplacePrivilegeOnRoleService.java +++ b/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddOrReplacePrivilegeOnRoleService.java @@ -46,11 +46,13 @@ public class PrivilegeAddOrReplacePrivilegeOnRoleService li.strolch.runtime.privilege.PrivilegeHandler strolchPrivilegeHandler = getContainer().getPrivilegeHandler(); PrivilegeHandler privilegeHandler = strolchPrivilegeHandler.getPrivilegeHandler(); - RoleRep role = privilegeHandler.addOrReplacePrivilegeOnRole(getCertificate(), arg.roleName, arg.privilegeRep); - privilegeHandler.persist(getCertificate()); - + RoleRep role; try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_MODIFY_ROLE)) { tx.setSuppressAudits(true); + + role = privilegeHandler.addOrReplacePrivilegeOnRole(getCertificate(), arg.roleName, arg.privilegeRep); + privilegeHandler.persist(getCertificate()); + Audit audit = tx .auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE, StrolchPrivilegeConstants.ROLE, role.getName()); diff --git a/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddRoleService.java b/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddRoleService.java index d27ceac84..72834060d 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddRoleService.java +++ b/li.strolch.service/src/main/java/li/strolch/service/privilege/roles/PrivilegeAddRoleService.java @@ -44,11 +44,13 @@ public class PrivilegeAddRoleService extends AbstractService roles.add(e.getAsString())); String username = arg.objectId; - UserRep user = privilegeHandler.getUser(getCertificate(), username); - // first add new roles - boolean changed = false; - for (String role : roles) { - if (!user.hasRole(role)) { - user = privilegeHandler.addRoleToUser(getCertificate(), username, role); - changed = true; + UserRep user; + try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER)) { + tx.setSuppressAudits(true); + + user = privilegeHandler.getUser(getCertificate(), username); + + // first add new roles + boolean changed = false; + for (String role : roles) { + if (!user.hasRole(role)) { + user = privilegeHandler.addRoleToUser(getCertificate(), username, role); + changed = true; + } } - } - // handle removed roles - for (String role : user.getRoles()) { - if (!roles.contains(role)) { - user = privilegeHandler.removeRoleFromUser(getCertificate(), username, role); - changed = true; + // handle removed roles + for (String role : user.getRoles()) { + if (!roles.contains(role)) { + user = privilegeHandler.removeRoleFromUser(getCertificate(), username, role); + changed = true; + } } - } - if (changed) { - try (StrolchTransaction tx = openArgOrUserTx(arg, PrivilegeHandler.PRIVILEGE_ADD_ROLE_TO_USER)) { - tx.setSuppressAudits(true); + if (changed) { Audit audit = tx.auditFrom(AccessType.UPDATE, StrolchPrivilegeConstants.PRIVILEGE, StrolchPrivilegeConstants.USER, user.getUsername()); tx.getAuditTrail().add(tx, audit); diff --git a/li.strolch.service/src/main/java/li/strolch/service/privilege/users/PrivilegeUpdateUserService.java b/li.strolch.service/src/main/java/li/strolch/service/privilege/users/PrivilegeUpdateUserService.java index 716076fab..bdd8da872 100644 --- a/li.strolch.service/src/main/java/li/strolch/service/privilege/users/PrivilegeUpdateUserService.java +++ b/li.strolch.service/src/main/java/li/strolch/service/privilege/users/PrivilegeUpdateUserService.java @@ -45,11 +45,13 @@ public class PrivilegeUpdateUserService extends AbstractService