diff --git a/resources/adempiere-grpc-server.pb b/resources/adempiere-grpc-server.pb index 53234e2a..8890f363 100644 Binary files a/resources/adempiere-grpc-server.pb and b/resources/adempiere-grpc-server.pb differ diff --git a/src/main/java/org/spin/grpc/logic/RecordManagementServiceLogic.java b/src/main/java/org/spin/grpc/logic/RecordManagementServiceLogic.java index 7ae26f48..8ade8fc2 100644 --- a/src/main/java/org/spin/grpc/logic/RecordManagementServiceLogic.java +++ b/src/main/java/org/spin/grpc/logic/RecordManagementServiceLogic.java @@ -21,15 +21,22 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import org.adempiere.core.domains.models.I_AD_Private_Access; +import org.adempiere.core.domains.models.I_AD_Record_Access; +import org.adempiere.core.domains.models.I_AD_Role; import org.adempiere.core.domains.models.I_AD_Tab; import org.adempiere.core.domains.models.I_AD_Window; import org.adempiere.exceptions.AdempiereException; import org.adempiere.model.ZoomInfoFactory; +import org.compiere.model.MPrivateAccess; import org.compiere.model.MQuery; +import org.compiere.model.MRecordAccess; +import org.compiere.model.MRole; import org.compiere.model.MTab; import org.compiere.model.MTable; import org.compiere.model.MWindow; import org.compiere.model.PO; +import org.compiere.model.Query; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; @@ -37,11 +44,16 @@ import org.compiere.util.Util; import org.spin.backend.grpc.record_management.ExistsRecordReferencesRequest; import org.spin.backend.grpc.record_management.ExistsRecordReferencesResponse; +import org.spin.backend.grpc.record_management.GetRecordAccessRequest; import org.spin.backend.grpc.record_management.ListRecordReferencesRequest; import org.spin.backend.grpc.record_management.ListRecordReferencesResponse; import org.spin.backend.grpc.record_management.ListZoomWindowsRequest; import org.spin.backend.grpc.record_management.ListZoomWindowsResponse; +import org.spin.backend.grpc.record_management.PrivateAccess; +import org.spin.backend.grpc.record_management.RecordAccess; +import org.spin.backend.grpc.record_management.RecordAccessRole; import org.spin.backend.grpc.record_management.RecordReferenceInfo; +import org.spin.backend.grpc.record_management.SetRecordAccessRequest; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordRequest; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordResponse; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordsBatchRequest; @@ -488,4 +500,238 @@ public static ListRecordReferencesResponse.Builder listRecordReferences(ListReco return builder; } + + /** + * Convert Context Info Value from query + * @param request + * @return + */ + public static PrivateAccess.Builder convertPrivateAccess(Properties context, MPrivateAccess privateAccess) { + PrivateAccess.Builder builder = PrivateAccess.newBuilder(); + if(privateAccess == null) { + return builder; + } + // Table + MTable table = MTable.get(Env.getCtx(), privateAccess.getAD_Table_ID()); + // Set values + builder.setTableName(table.getTableName()); + builder.setRecordId(privateAccess.getRecord_ID()); + builder.setIsLocked(privateAccess.isActive()); + // Return values + return builder; + } + + + + /** + * Convert Record Access + * @param request + * @return + */ + public static RecordAccess.Builder convertRecordAccess(GetRecordAccessRequest request) { + // validate and get table + final MTable table = RecordUtil.validateAndGetTable( + request.getTableName() + ); + // + int tableId = table.getAD_Table_ID(); + int recordId = request.getRecordId(); + RecordAccess.Builder builder = RecordAccess.newBuilder() + .setTableName( + StringManager.getValidString( + request.getTableName() + ) + ) + .setRecordId(recordId) + ; + // Populate access List + getRecordAccess(tableId, recordId, null).parallelStream().forEach(recordAccess -> { + MRole role = MRole.get(Env.getCtx(), recordAccess.getAD_Role_ID()); + builder.addCurrentRoles(RecordAccessRole.newBuilder() + .setId(role.getAD_Role_ID()) + .setName( + StringManager.getValidString( + role.getName() + ) + ) + .setIsActive(recordAccess.isActive()) + .setIsDependentEntities(recordAccess.isDependentEntities()) + .setIsExclude(recordAccess.isExclude()) + .setIsReadOnly(recordAccess.isReadOnly())); + }); + // Populate roles list + getRolesList(null).parallelStream().forEach(role -> { + builder.addAvailableRoles( + RecordAccessRole.newBuilder() + .setId(role.getAD_Role_ID()) + .setName( + StringManager.getValidString( + role.getName() + ) + ) + ); + }); + return builder; + } + + /** + * Get record access from client, role , table id and record id + * @param tableId + * @param recordId + * @param transactionName + * @return + */ + public static List getRecordAccess(int tableId, int recordId, String transactionName) { + return new Query( + Env.getCtx(), + I_AD_Record_Access.Table_Name, + "AD_Table_ID = ? " + + "AND Record_ID = ? " + + "AND AD_Client_ID = ?", + transactionName + ) + .setParameters(tableId, recordId, Env.getAD_Client_ID(Env.getCtx())) + .list() + ; + } + + /** + * Get role for this client + * @param transactionName + * @return + */ + public static List getRolesList(String transactionName) { + return new Query( + Env.getCtx(), + I_AD_Role.Table_Name, + null, + transactionName + ) + .setClient_ID() + .setOnlyActiveRecords(true) + .list() + ; + } + + /** + * save record Access + * @param request + * @return + */ + public static RecordAccess.Builder saveRecordAccess(SetRecordAccessRequest request) { + // validate and get table + final MTable table = RecordUtil.validateAndGetTable( + request.getTableName() + ); + if(request.getRecordId() <= 0) { + throw new AdempiereException("@Record_ID@ @NotFound@"); + } + // + RecordAccess.Builder builder = RecordAccess.newBuilder(); + Trx.run(transactionName -> { + int tableId = table.getAD_Table_ID(); + AtomicInteger recordId = new AtomicInteger(request.getRecordId()); + builder.setTableName( + StringManager.getValidString( + table.getTableName() + ) + ) + .setRecordId(recordId.get()) + ; + // Delete old + DB.executeUpdateEx("DELETE FROM AD_Record_Access " + + "WHERE AD_Table_ID = ? " + + "AND Record_ID = ? " + + "AND AD_Client_ID = ?", new Object[]{tableId, recordId.get(), Env.getAD_Client_ID(Env.getCtx())}, transactionName); + // Add new record access + request.getRecordAccessesList().parallelStream().forEach(recordAccessToSet -> { + int roleId = recordAccessToSet.getId(); + if(roleId <= 0) { + throw new AdempiereException("@AD_Role_ID@ @NotFound@"); + } + MRole role = MRole.get(Env.getCtx(), roleId); + MRecordAccess recordAccess = new MRecordAccess(Env.getCtx(), role.getAD_Role_ID(), tableId, recordId.get(), transactionName); + recordAccess.setIsActive(recordAccessToSet.getIsActive()); + recordAccess.setIsExclude(recordAccessToSet.getIsExclude()); + recordAccess.setIsDependentEntities(recordAccessToSet.getIsDependentEntities()); + recordAccess.setIsReadOnly(recordAccessToSet.getIsReadOnly()); + recordAccess.saveEx(); + // Add current roles + builder.addCurrentRoles( + RecordAccessRole.newBuilder() + .setId(role.getAD_Role_ID()) + .setName( + StringManager.getValidString( + role.getName() + ) + ) + .setIsActive(recordAccess.isActive()) + .setIsDependentEntities(recordAccess.isDependentEntities()) + .setIsExclude(recordAccess.isExclude()) + .setIsReadOnly(recordAccess.isReadOnly()) + ); + }); + // Populate roles list + getRolesList(transactionName).parallelStream().forEach(roleToGet -> { + builder.addAvailableRoles( + RecordAccessRole.newBuilder() + .setId( + roleToGet.getAD_Role_ID() + ) + ); + }); + }); + // + return builder; + } + + + /** + * Get private access from table, record id and user id + * @param Env.getCtx() + * @param tableName + * @param recordId + * @param userUuid + * @param transactionName + * @return + */ + public static MPrivateAccess getPrivateAccess(Properties context, String tableName, int recordId, int userId, String transactionName) { + return new Query( + Env.getCtx(), + I_AD_Private_Access.Table_Name, + "EXISTS(SELECT 1 FROM AD_Table t WHERE t.AD_Table_ID = AD_Private_Access.AD_Table_ID AND t.TableName = ?) " + + "AND Record_ID = ? " + + "AND AD_User_ID = ?", + transactionName + ) + .setParameters(tableName, recordId, userId) + .first() + ; + } + + + /** + * Lock and unlock private access + * @param Env.getCtx() + * @param request + * @param lock + * @param transactionName + * @return + */ + public static PrivateAccess.Builder lockUnlockPrivateAccess(Properties context, String tableName, int recordId, int userId, boolean lock, String transactionName) { + MPrivateAccess privateAccess = getPrivateAccess(Env.getCtx(), tableName, recordId, userId, transactionName); + // Create new + if(privateAccess == null + || privateAccess.getAD_Table_ID() == 0) { + MTable table = MTable.get(Env.getCtx(), tableName); + // Set values + privateAccess = new MPrivateAccess(Env.getCtx(), userId, table.getAD_Table_ID(), recordId); + } + // Set active + privateAccess.setIsActive(lock); + privateAccess.saveEx(transactionName); + // Convert Private Access + return convertPrivateAccess(Env.getCtx(), privateAccess); + } + } diff --git a/src/main/java/org/spin/grpc/service/RecordManagement.java b/src/main/java/org/spin/grpc/service/RecordManagement.java index e7342e6a..0131eb13 100644 --- a/src/main/java/org/spin/grpc/service/RecordManagement.java +++ b/src/main/java/org/spin/grpc/service/RecordManagement.java @@ -15,18 +15,29 @@ package org.spin.grpc.service; import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.MPrivateAccess; +import org.compiere.model.MTable; +import org.compiere.model.MUser; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.spin.backend.grpc.record_management.RecordManagementGrpc.RecordManagementImplBase; +import org.spin.backend.grpc.record_management.SetRecordAccessRequest; import org.spin.backend.grpc.record_management.ExistsRecordReferencesRequest; import org.spin.backend.grpc.record_management.ExistsRecordReferencesResponse; +import org.spin.backend.grpc.record_management.GetPrivateAccessRequest; +import org.spin.backend.grpc.record_management.GetRecordAccessRequest; import org.spin.backend.grpc.record_management.ListRecordReferencesRequest; import org.spin.backend.grpc.record_management.ListRecordReferencesResponse; import org.spin.backend.grpc.record_management.ListZoomWindowsRequest; import org.spin.backend.grpc.record_management.ListZoomWindowsResponse; +import org.spin.backend.grpc.record_management.LockPrivateAccessRequest; +import org.spin.backend.grpc.record_management.PrivateAccess; +import org.spin.backend.grpc.record_management.RecordAccess; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordRequest; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordResponse; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordsBatchRequest; import org.spin.backend.grpc.record_management.ToggleIsActiveRecordsBatchResponse; +import org.spin.backend.grpc.record_management.UnlockPrivateAccessRequest; import org.spin.grpc.logic.RecordManagementServiceLogic; import io.grpc.Status; @@ -154,4 +165,164 @@ public void listRecordReferences(ListRecordReferencesRequest request, StreamObse } } + + @Override + /** + * @param request + * @param responseObserver + */ + public void lockPrivateAccess(LockPrivateAccessRequest request, StreamObserver responseObserver) { + try { + if(request == null) { + throw new AdempiereException("Object Request Null"); + } + + int recordId = request.getRecordId(); + if (recordId <= 0) { + throw new AdempiereException("@Record_ID@ @NotFound@"); + } + MUser user = MUser.get(Env.getCtx()); + PrivateAccess.Builder privateaccess = RecordManagementServiceLogic.lockUnlockPrivateAccess( + Env.getCtx(), + request.getTableName(), + recordId, + user.getAD_User_ID(), + true, + null + ); + responseObserver.onNext(privateaccess.build()); + responseObserver.onCompleted(); + } catch (Exception e) { + log.severe(e.getLocalizedMessage()); + e.printStackTrace(); + responseObserver.onError( + Status.INTERNAL + .withDescription(e.getLocalizedMessage()) + .withCause(e) + .asRuntimeException() + ); + } + } + + @Override + /** + * @param request + * @param responseObserver + */ + public void unlockPrivateAccess(UnlockPrivateAccessRequest request, StreamObserver responseObserver) { + try { + if(request == null) { + throw new AdempiereException("Object Request Null"); + } + + int recordId = request.getRecordId(); + if (recordId <= 0) { + throw new AdempiereException("@Record_ID@ @NotFound@"); + } + MUser user = MUser.get(Env.getCtx()); + PrivateAccess.Builder privateaccess = RecordManagementServiceLogic.lockUnlockPrivateAccess( + Env.getCtx(), + request.getTableName(), + recordId, + user.getAD_User_ID(), + false, + null + ); + responseObserver.onNext(privateaccess.build()); + responseObserver.onCompleted(); + } catch (Exception e) { + log.severe(e.getLocalizedMessage()); + responseObserver.onError( + Status.INTERNAL + .withDescription(e.getLocalizedMessage()) + .withCause(e) + .asRuntimeException() + ); + } + } + + @Override + public void getPrivateAccess(GetPrivateAccessRequest request, StreamObserver responseObserver) { + try { + if(request == null) { + throw new AdempiereException("Object Request Null"); + } + + int recordId = request.getRecordId(); + if (recordId <= 0) { + throw new AdempiereException("@Record_ID@ @NotFound@"); + } + MUser user = MUser.get(Env.getCtx()); + MPrivateAccess privateAccess = RecordManagementServiceLogic.getPrivateAccess( + Env.getCtx(), + request.getTableName(), + recordId, + user.getAD_User_ID(), + null + ); + if(privateAccess == null + || privateAccess.getAD_Table_ID() == 0) { + MTable table = MTable.get(Env.getCtx(), request.getTableName()); + // Set values + privateAccess = new MPrivateAccess(Env.getCtx(), user.getAD_User_ID(), table.getAD_Table_ID(), recordId); + privateAccess.setIsActive(false); + } + PrivateAccess.Builder privateaccess = RecordManagementServiceLogic.convertPrivateAccess( + Env.getCtx(), + privateAccess + ); + responseObserver.onNext(privateaccess.build()); + responseObserver.onCompleted(); + } catch (Exception e) { + log.severe(e.getLocalizedMessage()); + responseObserver.onError( + Status.INTERNAL + .withDescription(e.getLocalizedMessage()) + .withCause(e) + .asRuntimeException() + ); + } + } + + + @Override + public void getRecordAccess(GetRecordAccessRequest request, StreamObserver responseObserver) { + try { + if(request == null) { + throw new AdempiereException("Object Request Null"); + } + RecordAccess.Builder recordAccess = RecordManagementServiceLogic.convertRecordAccess(request); + responseObserver.onNext(recordAccess.build()); + responseObserver.onCompleted(); + } catch (Exception e) { + log.severe(e.getLocalizedMessage()); + responseObserver.onError( + Status.INTERNAL + .withDescription(e.getLocalizedMessage()) + .withCause(e) + .asRuntimeException() + ); + } + } + + @Override + public void setRecordAccess(SetRecordAccessRequest request, StreamObserver responseObserver) { + try { + if(request == null) { + throw new AdempiereException("Object Request Null"); + } + RecordAccess.Builder recordAccess = RecordManagementServiceLogic.saveRecordAccess(request); + responseObserver.onNext(recordAccess.build()); + responseObserver.onCompleted(); + } catch (Exception e) { + log.severe(e.getLocalizedMessage()); + responseObserver.onError( + Status.INTERNAL + .withDescription(e.getLocalizedMessage()) + .withCause(e) + .asRuntimeException() + ); + } + } + } diff --git a/src/main/java/org/spin/grpc/service/UserInterface.java b/src/main/java/org/spin/grpc/service/UserInterface.java index d9f1d149..0ff46dd6 100644 --- a/src/main/java/org/spin/grpc/service/UserInterface.java +++ b/src/main/java/org/spin/grpc/service/UserInterface.java @@ -39,9 +39,6 @@ import org.adempiere.core.domains.models.I_AD_Element; import org.adempiere.core.domains.models.I_AD_EntityType; import org.adempiere.core.domains.models.I_AD_Language; -import org.adempiere.core.domains.models.I_AD_Private_Access; -import org.adempiere.core.domains.models.I_AD_Record_Access; -import org.adempiere.core.domains.models.I_AD_Role; import org.adempiere.core.domains.models.I_AD_Table; import org.adempiere.core.domains.models.I_CM_Chat; import org.adempiere.core.domains.models.I_R_MailText; @@ -66,13 +63,10 @@ import org.compiere.model.MField; import org.compiere.model.MMailText; import org.compiere.model.MMessage; -import org.compiere.model.MPrivateAccess; -import org.compiere.model.MRecordAccess; import org.compiere.model.MRole; import org.compiere.model.MRule; import org.compiere.model.MTab; import org.compiere.model.MTable; -import org.compiere.model.MUser; import org.compiere.model.PO; import org.compiere.model.POAdapter; import org.compiere.model.Query; @@ -92,8 +86,6 @@ import org.spin.backend.grpc.user_interface.ExportBrowserItemsRequest; import org.spin.backend.grpc.user_interface.ExportBrowserItemsResponse; import org.spin.backend.grpc.user_interface.GetContextInfoValueRequest; -import org.spin.backend.grpc.user_interface.GetPrivateAccessRequest; -import org.spin.backend.grpc.user_interface.GetRecordAccessRequest; import org.spin.backend.grpc.user_interface.GetTabEntityRequest; import org.spin.backend.grpc.user_interface.ListBrowserItemsRequest; import org.spin.backend.grpc.user_interface.ListBrowserItemsResponse; @@ -105,17 +97,11 @@ import org.spin.backend.grpc.user_interface.ListTranslationsResponse; import org.spin.backend.grpc.user_interface.ListTreeNodesRequest; import org.spin.backend.grpc.user_interface.ListTreeNodesResponse; -import org.spin.backend.grpc.user_interface.LockPrivateAccessRequest; import org.spin.backend.grpc.user_interface.MailTemplate; -import org.spin.backend.grpc.user_interface.PrivateAccess; -import org.spin.backend.grpc.user_interface.RecordAccess; -import org.spin.backend.grpc.user_interface.RecordAccessRole; import org.spin.backend.grpc.user_interface.RollbackEntityRequest; import org.spin.backend.grpc.user_interface.RunCalloutRequest; import org.spin.backend.grpc.user_interface.SaveTabSequencesRequest; -import org.spin.backend.grpc.user_interface.SetRecordAccessRequest; import org.spin.backend.grpc.user_interface.Translation; -import org.spin.backend.grpc.user_interface.UnlockPrivateAccessRequest; import org.spin.backend.grpc.user_interface.UpdateBrowserEntityRequest; import org.spin.backend.grpc.user_interface.UpdateTabEntityRequest; import org.spin.backend.grpc.user_interface.UserInterfaceGrpc.UserInterfaceImplBase; @@ -335,100 +321,6 @@ private Entity.Builder updateBrowserEntity(UpdateBrowserEntityRequest request) { } - - @Override - /** - * TODO: Replace LockPrivateAccessRequest with GetPrivateAccessRequest - * @param request - * @param responseObserver - */ - public void lockPrivateAccess(LockPrivateAccessRequest request, StreamObserver responseObserver) { - try { - if(request == null) { - throw new AdempiereException("Object Request Null"); - } - - int recordId = request.getId(); - if (recordId <= 0) { - throw new AdempiereException("@Record_ID@ @NotFound@"); - } - MUser user = MUser.get(Env.getCtx()); - PrivateAccess.Builder privateaccess = lockUnlockPrivateAccess(Env.getCtx(), request.getTableName(), recordId, user.getAD_User_ID(), true, null); - responseObserver.onNext(privateaccess.build()); - responseObserver.onCompleted(); - } catch (Exception e) { - log.severe(e.getLocalizedMessage()); - e.printStackTrace(); - responseObserver.onError( - Status.INTERNAL - .withDescription(e.getLocalizedMessage()) - .withCause(e) - .asRuntimeException() - ); - } - } - - @Override - /** - * TODO: Replace UnlockPrivateAccessRequest with GetPrivateAccessRequest - * @param request - * @param responseObserver - */ - public void unlockPrivateAccess(UnlockPrivateAccessRequest request, StreamObserver responseObserver) { - try { - if(request == null) { - throw new AdempiereException("Object Request Null"); - } - - int recordId = request.getId(); - if (recordId <= 0) { - throw new AdempiereException("@Record_ID@ @NotFound@"); - } - MUser user = MUser.get(Env.getCtx()); - PrivateAccess.Builder privateaccess = lockUnlockPrivateAccess(Env.getCtx(), request.getTableName(), recordId, user.getAD_User_ID(), false, null); - responseObserver.onNext(privateaccess.build()); - responseObserver.onCompleted(); - } catch (Exception e) { - log.severe(e.getLocalizedMessage()); - responseObserver.onError(Status.INTERNAL - .withDescription(e.getLocalizedMessage()) - .withCause(e) - .asRuntimeException()); - } - } - - @Override - public void getPrivateAccess(GetPrivateAccessRequest request, StreamObserver responseObserver) { - try { - if(request == null) { - throw new AdempiereException("Object Request Null"); - } - - int recordId = request.getId(); - if (recordId <= 0) { - throw new AdempiereException("@Record_ID@ @NotFound@"); - } - MUser user = MUser.get(Env.getCtx()); - MPrivateAccess privateAccess = getPrivateAccess(Env.getCtx(), request.getTableName(), recordId, user.getAD_User_ID(), null); - if(privateAccess == null - || privateAccess.getAD_Table_ID() == 0) { - MTable table = MTable.get(Env.getCtx(), request.getTableName()); - // Set values - privateAccess = new MPrivateAccess(Env.getCtx(), user.getAD_User_ID(), table.getAD_Table_ID(), recordId); - privateAccess.setIsActive(false); - } - PrivateAccess.Builder privateaccess = convertPrivateAccess(Env.getCtx(), privateAccess); - responseObserver.onNext(privateaccess.build()); - responseObserver.onCompleted(); - } catch (Exception e) { - log.severe(e.getLocalizedMessage()); - responseObserver.onError(Status.INTERNAL - .withDescription(e.getLocalizedMessage()) - .withCause(e) - .asRuntimeException()); - } - } - @Override public void getContextInfoValue(GetContextInfoValueRequest request, StreamObserver responseObserver) { try { @@ -483,42 +375,6 @@ public void createChatEntry(CreateChatEntryRequest request, StreamObserver responseObserver) { - try { - if(request == null) { - throw new AdempiereException("Object Request Null"); - } - RecordAccess.Builder recordAccess = convertRecordAccess(request); - responseObserver.onNext(recordAccess.build()); - responseObserver.onCompleted(); - } catch (Exception e) { - log.severe(e.getLocalizedMessage()); - responseObserver.onError(Status.INTERNAL - .withDescription(e.getLocalizedMessage()) - .withCause(e) - .asRuntimeException()); - } - } - - @Override - public void setRecordAccess(SetRecordAccessRequest request, StreamObserver responseObserver) { - try { - if(request == null) { - throw new AdempiereException("Object Request Null"); - } - RecordAccess.Builder recordAccess = saveRecordAccess(request); - responseObserver.onNext(recordAccess.build()); - responseObserver.onCompleted(); - } catch (Exception e) { - log.severe(e.getLocalizedMessage()); - responseObserver.onError(Status.INTERNAL - .withDescription(e.getLocalizedMessage()) - .withCause(e) - .asRuntimeException()); - } - } - /** @@ -1085,198 +941,7 @@ private Entity.Builder updateTabEntity(UpdateTabEntityRequest request) { return builder; } - - - /** - * Convert Record Access - * @param request - * @return - */ - private RecordAccess.Builder convertRecordAccess(GetRecordAccessRequest request) { - // validate and get table - final MTable table = RecordUtil.validateAndGetTable( - request.getTableName() - ); - // - int tableId = table.getAD_Table_ID(); - int recordId = request.getId(); - RecordAccess.Builder builder = RecordAccess.newBuilder() - .setTableName( - StringManager.getValidString( - request.getTableName() - ) - ) - .setId(recordId) - ; - // Populate access List - getRecordAccess(tableId, recordId, null).parallelStream().forEach(recordAccess -> { - MRole role = MRole.get(Env.getCtx(), recordAccess.getAD_Role_ID()); - builder.addCurrentRoles(RecordAccessRole.newBuilder() - .setRoleId(role.getAD_Role_ID()) - .setRoleName( - StringManager.getValidString( - role.getName() - ) - ) - .setIsActive(recordAccess.isActive()) - .setIsDependentEntities(recordAccess.isDependentEntities()) - .setIsExclude(recordAccess.isExclude()) - .setIsReadOnly(recordAccess.isReadOnly())); - }); - // Populate roles list - getRolesList(null).parallelStream().forEach(role -> { - builder.addAvailableRoles( - RecordAccessRole.newBuilder() - .setRoleId(role.getAD_Role_ID()) - .setRoleName( - StringManager.getValidString( - role.getName() - ) - ) - ); - }); - return builder; - } - /** - * Get record access from client, role , table id and record id - * @param tableId - * @param recordId - * @param transactionName - * @return - */ - private List getRecordAccess(int tableId, int recordId, String transactionName) { - return new Query(Env.getCtx(), I_AD_Record_Access.Table_Name,"AD_Table_ID = ? " - + "AND Record_ID = ? " - + "AND AD_Client_ID = ?", transactionName) - .setParameters(tableId, recordId, Env.getAD_Client_ID(Env.getCtx())) - .list(); - } - - /** - * Get role for this client - * @param transactionName - * @return - */ - private List getRolesList(String transactionName) { - return new Query(Env.getCtx(), I_AD_Role.Table_Name, null, transactionName) - .setClient_ID() - .setOnlyActiveRecords(true) - .list(); - } - - /** - * save record Access - * @param request - * @return - */ - private RecordAccess.Builder saveRecordAccess(SetRecordAccessRequest request) { - // validate and get table - final MTable table = RecordUtil.validateAndGetTable( - request.getTableName() - ); - if(request.getId() <= 0) { - throw new AdempiereException("@Record_ID@ @NotFound@"); - } - // - RecordAccess.Builder builder = RecordAccess.newBuilder(); - Trx.run(transactionName -> { - int tableId = table.getAD_Table_ID(); - AtomicInteger recordId = new AtomicInteger(request.getId()); - builder.setTableName( - StringManager.getValidString( - table.getTableName() - ) - ) - .setId(recordId.get()) - ; - // Delete old - DB.executeUpdateEx("DELETE FROM AD_Record_Access " - + "WHERE AD_Table_ID = ? " - + "AND Record_ID = ? " - + "AND AD_Client_ID = ?", new Object[]{tableId, recordId.get(), Env.getAD_Client_ID(Env.getCtx())}, transactionName); - // Add new record access - request.getRecordAccessesList().parallelStream().forEach(recordAccessToSet -> { - int roleId = recordAccessToSet.getRoleId(); - if(roleId <= 0) { - throw new AdempiereException("@AD_Role_ID@ @NotFound@"); - } - MRole role = MRole.get(Env.getCtx(), roleId); - MRecordAccess recordAccess = new MRecordAccess(Env.getCtx(), role.getAD_Role_ID(), tableId, recordId.get(), transactionName); - recordAccess.setIsActive(recordAccessToSet.getIsActive()); - recordAccess.setIsExclude(recordAccessToSet.getIsExclude()); - recordAccess.setIsDependentEntities(recordAccessToSet.getIsDependentEntities()); - recordAccess.setIsReadOnly(recordAccessToSet.getIsReadOnly()); - recordAccess.saveEx(); - // Add current roles - builder.addCurrentRoles( - RecordAccessRole.newBuilder() - .setRoleId(role.getAD_Role_ID()) - .setRoleName( - StringManager.getValidString( - role.getName() - ) - ) - .setIsActive(recordAccess.isActive()) - .setIsDependentEntities(recordAccess.isDependentEntities()) - .setIsExclude(recordAccess.isExclude()) - .setIsReadOnly(recordAccess.isReadOnly()) - ); - }); - // Populate roles list - getRolesList(transactionName).parallelStream().forEach(roleToGet -> { - builder.addAvailableRoles( - RecordAccessRole.newBuilder() - .setRoleId(roleToGet.getAD_Role_ID()) - ); - }); - }); - // - return builder; - } - - - /** - * Get private access from table, record id and user id - * @param Env.getCtx() - * @param tableName - * @param recordId - * @param userUuid - * @param transactionName - * @return - */ - private MPrivateAccess getPrivateAccess(Properties context, String tableName, int recordId, int userId, String transactionName) { - return new Query(Env.getCtx(), I_AD_Private_Access.Table_Name, "EXISTS(SELECT 1 FROM AD_Table t WHERE t.AD_Table_ID = AD_Private_Access.AD_Table_ID AND t.TableName = ?) " - + "AND Record_ID = ? " - + "AND AD_User_ID = ?", transactionName) - .setParameters(tableName, recordId, userId) - .first(); - } - - - /** - * Lock and unlock private access - * @param Env.getCtx() - * @param request - * @param lock - * @param transactionName - * @return - */ - private PrivateAccess.Builder lockUnlockPrivateAccess(Properties context, String tableName, int recordId, int userId, boolean lock, String transactionName) { - MPrivateAccess privateAccess = getPrivateAccess(Env.getCtx(), tableName, recordId, userId, transactionName); - // Create new - if(privateAccess == null - || privateAccess.getAD_Table_ID() == 0) { - MTable table = MTable.get(Env.getCtx(), tableName); - // Set values - privateAccess = new MPrivateAccess(Env.getCtx(), userId, table.getAD_Table_ID(), recordId); - } - // Set active - privateAccess.setIsActive(lock); - privateAccess.saveEx(transactionName); - // Convert Private Access - return convertPrivateAccess(Env.getCtx(), privateAccess); - } /** @@ -1582,26 +1247,6 @@ private ContextInfoValue.Builder convertContextInfoValue(Properties context, Get // Return values return builder; } - - /** - * Convert Context Info Value from query - * @param request - * @return - */ - private PrivateAccess.Builder convertPrivateAccess(Properties context, MPrivateAccess privateAccess) { - PrivateAccess.Builder builder = PrivateAccess.newBuilder(); - if(privateAccess == null) { - return builder; - } - // Table - MTable table = MTable.get(Env.getCtx(), privateAccess.getAD_Table_ID()); - // Set values - builder.setTableName(table.getTableName()); - builder.setId(privateAccess.getRecord_ID()); - builder.setIsLocked(privateAccess.isActive()); - // Return values - return builder; - } diff --git a/src/main/proto/record_management.proto b/src/main/proto/record_management.proto index 79a9de07..a8dba337 100644 --- a/src/main/proto/record_management.proto +++ b/src/main/proto/record_management.proto @@ -57,6 +57,38 @@ service RecordManagement { rpc ListRecordReferences(ListRecordReferencesRequest) returns (ListRecordReferencesResponse) { option (google.api.http) = { get: "/record-management/references/{tab_id}/{record_id}" }; } + + // Private Access + rpc GetPrivateAccess(GetPrivateAccessRequest) returns (PrivateAccess) { + option (google.api.http) = { + get: "/record-management/private-access/{table_name}/{record_id}" + }; + } + rpc LockPrivateAccess(LockPrivateAccessRequest) returns (PrivateAccess) { + option (google.api.http) = { + patch: "/record-management/private-access/{table_name}/{record_id}/lock", + body: "*" + }; + } + rpc UnlockPrivateAccess(UnlockPrivateAccessRequest) returns (PrivateAccess) { + option (google.api.http) = { + patch: "/record-management/private-access/{table_name}/{record_id}/unlock", + body: "*" + }; + } + + // Record Access + rpc GetRecordAccess(GetRecordAccessRequest) returns (RecordAccess) { + option (google.api.http) = { + get: "/record-management/record-access/{table_name}/{record_id}" + }; + } + rpc SetRecordAccess(SetRecordAccessRequest) returns (RecordAccess) { + option (google.api.http) = { + patch: "/record-management/record-access/{table_name}/{record_id}", + body: "*" + }; + } } @@ -150,3 +182,51 @@ message ListZoomWindowsResponse { string display_column_name = 5; repeated ZoomWindow zoom_windows = 6; } + + +// Private Access +message PrivateAccess { + string table_name = 1; + int32 record_id = 2; + bool is_locked = 3; +} +message GetPrivateAccessRequest { + string table_name = 1; + int32 record_id = 2; +} +message LockPrivateAccessRequest { + string table_name = 1; + int32 record_id = 2; +} +message UnlockPrivateAccessRequest { + string table_name = 1; + int32 record_id = 2; +} + + +// Record Access +message RecordAccessRole { + int32 id = 1; + string uuid = 2; + string name = 3; + bool is_active = 4; + bool is_exclude = 5; + bool is_read_only = 6; + bool is_dependent_entities = 7; +} +message GetRecordAccessRequest { + string table_name = 1; + int32 record_id = 2; +} +message SetRecordAccessRequest { + string table_name = 1; + int32 record_id = 2; + repeated RecordAccessRole record_accesses = 3; +} +message RecordAccess { + string table_name = 1; + int32 record_id = 2; + string record_uuid = 3; + repeated RecordAccessRole available_roles = 4; + repeated RecordAccessRole current_roles = 5; +} diff --git a/src/main/proto/user_interface.proto b/src/main/proto/user_interface.proto index 2805ba96..1a0a439f 100644 --- a/src/main/proto/user_interface.proto +++ b/src/main/proto/user_interface.proto @@ -90,35 +90,6 @@ service UserInterface { rpc GetContextInfoValue(GetContextInfoValueRequest) returns (ContextInfoValue) { option (google.api.http) = { get: "/user-interface/context-info/{id}" }; } - // Get Private Access - rpc GetPrivateAccess(GetPrivateAccessRequest) returns (PrivateAccess) { - option (google.api.http) = { get: "/user-interface/private-access/{table_name}/{id}" }; - } - // Create Private Access - rpc LockPrivateAccess(LockPrivateAccessRequest) returns (PrivateAccess) { - option (google.api.http) = { - patch: "/user-interface/private-access/{table_name}/{id}/lock", - body: "*" - }; - } - // Change Private Access - rpc UnlockPrivateAccess(UnlockPrivateAccessRequest) returns (PrivateAccess) { - option (google.api.http) = { - patch: "/user-interface/private-access/{table_name}/{id}/unlock", - body: "*" - }; - } - // Get Record Access - rpc GetRecordAccess(GetRecordAccessRequest) returns (RecordAccess) { - option (google.api.http) = { get: "/user-interface/record-access/{table_name}/{id}" }; - } - // Set Record Access - rpc SetRecordAccess(SetRecordAccessRequest) returns (RecordAccess) { - option (google.api.http) = { - patch: "/user-interface/record-access/{table_name}/{id}", - body: "*" - }; - } // Add Chat Entry rpc CreateChatEntry(CreateChatEntryRequest) returns (ChatEntry) { option (google.api.http) = { @@ -158,58 +129,6 @@ message Translation { google.protobuf.Struct values = 2; } -// Role Access Request -message GetRecordAccessRequest { - string table_name = 1; - int32 id = 2; -} - -// Set Access Request -message SetRecordAccessRequest { - string table_name = 1; - int32 id = 2; - repeated RecordAccessRole record_accesses = 3; -} - -// Record Access Definition -message RecordAccess { - string table_name = 1; - int32 id = 2; - repeated RecordAccessRole available_roles = 3; - repeated RecordAccessRole current_roles = 4; -} - -// Record Access Stub -message RecordAccessRole { - int32 role_id = 1; - string role_name = 2; - bool is_active = 3; - bool is_exclude = 4; - bool is_read_only = 5; - bool is_dependent_entities = 6; -} - -// Private Access -message GetPrivateAccessRequest { - string table_name = 1; - int32 id = 2; -} - -message LockPrivateAccessRequest { - string table_name = 1; - int32 id = 2; -} - -message UnlockPrivateAccessRequest { - string table_name = 1; - int32 id = 2; -} - -message PrivateAccess { - string table_name = 1; - int32 id = 2; - bool is_locked = 3; -} // Empty message message RollbackEntityRequest {