diff --git a/iparapheur-amp/pom.xml b/iparapheur-amp/pom.xml index 2bd619450506a6b39d596be289728f99e5fd4bda..f3c3d1d64f8a1c2de49deb68b007bc152859a5c4 100644 --- a/iparapheur-amp/pom.xml +++ b/iparapheur-amp/pom.xml @@ -6,13 +6,13 @@ <parent> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </parent> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-amp</artifactId> <description>Parapheur electronique</description> <packaging>war</packaging> - <version>4.7.25-for-Alf3.4.c</version> + <version>4.7.26-rc.1-for-Alf3.4.c</version> <name>i-Parapheur AMP packaging</name> <url>http://maven.apache.org</url> <properties> @@ -65,13 +65,13 @@ <dependency> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-core</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </dependency> <dependency> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-mobile-webscripts</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </dependency> <dependency> diff --git a/iparapheur-core/pom.xml b/iparapheur-core/pom.xml index de30295d7275da4a61955ae0870a7039ac8b42f6..aa2eea11ef3fcf99c540f7f2442c517f46b3ae8d 100644 --- a/iparapheur-core/pom.xml +++ b/iparapheur-core/pom.xml @@ -5,14 +5,14 @@ <parent> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-core</artifactId> <packaging>jar</packaging> <name>iparapheur core module</name> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> <description>Parapheur electronique</description> <!-- General Info --> <url>https://adullact.net/projects/paraphelec/</url> @@ -294,7 +294,7 @@ <dependency> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-rules</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> <!-- exclusions> <exclusion> <artifactId>asm</artifactId> diff --git a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/DossierServiceImpl.java b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/DossierServiceImpl.java index 23e712f0661a30de90da649954155cbc903ed7f4..ce458e9b966988b4729838261c3283572ea2bd6b 100644 --- a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/DossierServiceImpl.java +++ b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/DossierServiceImpl.java @@ -403,6 +403,7 @@ public class DossierServiceImpl implements DossierService { props.put(ParapheurModel.PROP_SIGNATURE_PAPIER, false); props.put(ParapheurModel.PROP_TERMINE, false); props.put(ParapheurModel.PROP_RECUPERABLE, false); + props.put(ParapheurModel.PROP_FULL_CREATED, false); props.put(ParapheurModel.PROP_ORDERED_CHILDREN, true); @@ -607,11 +608,6 @@ public class DossierServiceImpl implements DossierService { // On récupère le nom du dossier dans la Map String nom = (String) properties.get(ContentModel.PROP_NAME); - NodeRef dossier = fileFolderService.searchSimple(corbeille, nom); - if (dossier == null) { - dossier = fileFolderService.create(corbeille, nom, ParapheurModel.TYPE_DOSSIER).getNodeRef(); - } - // ajout des propriétés Map<QName, Serializable> props = new HashMap<QName, Serializable>(); @@ -625,38 +621,46 @@ public class DossierServiceImpl implements DossierService { props.put(ParapheurModel.PROP_TERMINE, false); props.put(ParapheurModel.PROP_FULL_CREATED, false); props.put(ParapheurModel.PROP_RECUPERABLE, false); - // FIXME : propriété de Folder mais non présente dans ContModel.java, donc rajouté à ParapheurModel.java; - // éventuellement à modifier si ca change dans les prochaines versions d'alfresco props.put(ParapheurModel.PROP_ORDERED_CHILDREN, true); + props.put(ParapheurModel.PROP_STATUS_METIER, StatusMetier.STATUS_NON_LU); // merge avec les propriétés du dossier (properties override props) props.putAll(properties); - this.nodeService.setProperties(dossier, props); - - if (secretaire) { - this.nodeService.addAspect(dossier, ParapheurModel.ASPECT_SECRETARIAT, null); - } Map<QName, Serializable> pptes = new HashMap<QName, Serializable>(); pptes.put(ParapheurModel.PROP_EFFECTUEE, false); pptes.put(ParapheurModel.PROP_PASSE_PAR, parapheur); pptes.put(ParapheurModel.PROP_ACTION_DEMANDEE, "VISA"); - this.nodeService.createNode(dossier, ParapheurModel.CHILD_ASSOC_PREMIERE_ETAPE, - ParapheurModel.ASSOC_DOSSIER_ETAPE, ParapheurModel.TYPE_ETAPE_CIRCUIT, pptes); - // Define confidential permission - permissionService.deletePermissions(dossier); - permissionService.setInheritParentPermissions(dossier, false); - // PROPRIETAIRES - setPermission(dossier, "ROLE_PHOWNER_", parapheur, PermissionService.FULL_CONTROL); - // SECRETAIRES - setPermission(dossier, "ROLE_PHSECRETARIAT_", parapheur, PermissionService.FULL_CONTROL); - //DELEGUES - setPermission(dossier, "ROLE_PHDELEGATES_", parapheur, PermissionService.FULL_CONTROL); + NodeRef dossier = transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + NodeRef d = fileFolderService.searchSimple(corbeille, nom); + if (d == null) { + d = fileFolderService.create(corbeille, nom, ParapheurModel.TYPE_DOSSIER).getNodeRef(); + } + this.nodeService.setProperties(d, props); + + if (secretaire) { + this.nodeService.addAspect(d, ParapheurModel.ASPECT_SECRETARIAT, null); + } + this.nodeService.createNode(d, ParapheurModel.CHILD_ASSOC_PREMIERE_ETAPE, + ParapheurModel.ASSOC_DOSSIER_ETAPE, ParapheurModel.TYPE_ETAPE_CIRCUIT, pptes); - nodeService.setProperty(dossier, ParapheurModel.PROP_STATUS_METIER, StatusMetier.STATUS_NON_LU); + // Define confidential permission + permissionService.deletePermissions(d); + permissionService.setInheritParentPermissions(d, false); + // PROPRIETAIRES + setPermission(d, "ROLE_PHOWNER_", parapheur, PermissionService.FULL_CONTROL); + // SECRETAIRES + setPermission(d, "ROLE_PHSECRETARIAT_", parapheur, PermissionService.FULL_CONTROL); + //DELEGUES + setPermission(d, "ROLE_PHDELEGATES_", parapheur, PermissionService.FULL_CONTROL); + nodeService.setProperty(d, ParapheurModel.PROP_STATUS_METIER, StatusMetier.STATUS_NON_LU); + + return d; + }); List<Object> list = new ArrayList<Object>(); list.add(StatusMetier.STATUS_NON_LU); + auditWithNewBackend("ParapheurServiceCompat", "Création de dossier", dossier, list); return dossier; } @@ -674,7 +678,7 @@ public class DossierServiceImpl implements DossierService { values.put("message", message); values.put("dossier", dossier); values.put("list", (Serializable) list); - auditDAO.createAuditEntry(application.getId(), cal.getTimeInMillis(), AuthenticationUtil.getRunAsUser(), values); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> auditDAO.createAuditEntry(application.getId(), cal.getTimeInMillis(), AuthenticationUtil.getRunAsUser(), values)); //auditDAO.createAuditEntry(application.getId(), cal.getTimeInMillis(), this.authenticationService.getCurrentUserName(), values); } @@ -2212,26 +2216,20 @@ public class DossierServiceImpl implements DossierService { String setDossierPropertiesWithAuditTrail(@NotNull NodeRef dossierRef, @Nullable NodeRef parapheur, @NotNull Map<QName, Serializable> properties, boolean onlyAudit) { - UserTransaction utx = transactionService.getNonPropagatingUserTransaction(false); String result = null; - try { - utx.begin(); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + properties.put(ParapheurModel.PROP_FULL_CREATED, true); nodeService.setProperty(dossierRef, ParapheurModel.PROP_FULL_CREATED, true); - utx.commit(); - } catch (Exception e) { - try { - utx.rollback(); - } catch (Exception e2) { - e2.printStackTrace(); - } - } + return null; + }); + if (!onlyAudit) { Map<String, Serializable> propertiesString = new HashMap<String, Serializable>(); for (Map.Entry<QName, Serializable> entry : properties.entrySet()) { propertiesString.put(entry.getKey().toPrefixString(namespaceService), (entry.getValue() == null) ? null : entry.getValue()); } - result = setDossierProperties(dossierRef, propertiesString); + result = transactionService.getRetryingTransactionHelper().doInTransaction(() -> setDossierProperties(dossierRef, propertiesString)); } if (result == null) { diff --git a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/ParapheurServiceImpl.java b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/ParapheurServiceImpl.java index 63a7695f9b88f512979debabffb89e43c8c2233a..a7be583001c2b0761c1fe0418b2e6183e3317300 100755 --- a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/ParapheurServiceImpl.java +++ b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/ParapheurServiceImpl.java @@ -178,6 +178,7 @@ public final class ParapheurServiceImpl implements ParapheurService, Initializin private static Logger loggerTRACE = Logger.getLogger("TRACE." + ParapheurService.class.getName()); // BLEX private static Runtime rt = Runtime.getRuntime(); @Autowired + @Qualifier("NodeService") private NodeService nodeService; @Autowired private CopyService copyService; @@ -1617,7 +1618,10 @@ public final class ParapheurServiceImpl implements ParapheurService, Initializin // On vide le circuit précédent au cas où, à part la première étape NodeRef etapeSupprim = getFirstChild(premiereEtape, ParapheurModel.CHILD_ASSOC_PROCHAINE_ETAPE); if (etapeSupprim != null) { - this.nodeService.deleteNode(etapeSupprim); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + this.nodeService.deleteNode(etapeSupprim); + return null; + }); } if (circuit != null && !circuit.isEmpty()) { diff --git a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/TypesServiceImpl.java b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/TypesServiceImpl.java index 867160d51d13d0460cd97686dd2ada5c78d9008f..051bcd31a0ab5b26ed3167e8d2fdaddc3bff4239 100644 --- a/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/TypesServiceImpl.java +++ b/iparapheur-core/src/main/java/com/atolcd/parapheur/repo/impl/TypesServiceImpl.java @@ -56,6 +56,7 @@ import org.alfresco.service.cmr.repository.*; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.transaction.TransactionService; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.dom4j.Attribute; @@ -102,6 +103,8 @@ public final class TypesServiceImpl implements TypesService { @Autowired private AuthorityService authorityService; + @Autowired + TransactionService transactionService; @Override public boolean isDigitalSignatureMandatory(String typeName, String subtypeName) { @@ -1052,10 +1055,11 @@ public final class TypesServiceImpl implements TypesService { protected String getValueForSousType(String type, String sousType, String key) { - ContentReader subtypesReader = contentService.getReader( - getSubtypesNodeRef(type), - ContentModel.PROP_CONTENT); - + ContentReader subtypesReader = transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + return contentService.getReader( + getSubtypesNodeRef(type), + ContentModel.PROP_CONTENT); + }); try { SAXReader saxreader = new SAXReader(); Document docXml = saxreader.read(subtypesReader.getContentInputStream()); diff --git a/iparapheur-core/src/main/java/coop/libriciel/service/CreerDossierService.java b/iparapheur-core/src/main/java/coop/libriciel/service/CreerDossierService.java index 536fa74c7855e86abb593474e6d613faa151be0a..3d6032105b08e75547febea5b41b46656e804951 100644 --- a/iparapheur-core/src/main/java/coop/libriciel/service/CreerDossierService.java +++ b/iparapheur-core/src/main/java/coop/libriciel/service/CreerDossierService.java @@ -21,7 +21,7 @@ import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.filestore.FileContentReader; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.*; @@ -124,50 +124,54 @@ public class CreerDossierService { msg.setSeverite("FATAL"); // Do all verifications in a transaction - UserTransaction tx = transactionService.getUserTransaction(false); - - try { - tx.begin(); - + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { // Vérification de la requete this.checkAndBuildRequest(request, model); - // Création du dossier - this.createDossier(request, model); + return null; + }); + this.createDossier(request, model); - AuthenticationUtil.setRunAsUser(model.getUsername()); - authenticationComponent.setCurrentUser(model.getUsername()); + AuthenticationUtil.setRunAsUser(model.getUsername()); + authenticationComponent.setCurrentUser(model.getUsername()); + this.prepareContent(request, model); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { // Définition de la typologie et document principal this.setTypologyAndContents(request, model); + return null; + }); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { // Gestion des documents supplémentaires if (request.getDocumentsSupplementaires() != null) { log.debug(model.getLoggerPrefix() + " - Gestion des documents supplémentaires..."); this.handleDocsSupp(request, model); } + return null; + }); + + + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { // Gestion des documents annexes if (request.getDocumentsAnnexes() != null) { log.debug(model.getLoggerPrefix() + " - Gestion des annexes..."); this.handleDocsAnnexes(request, model); } - // Envoi du dossier dans le circuit - log.debug(model.getLoggerPrefix() + " - Envoi du document dans le circuit de validation..."); + return null; + }); + + // Envoi du dossier dans le circuit + log.debug(model.getLoggerPrefix() + " - Envoi du document dans le circuit de validation..."); + + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + // Gestion des documents annexes // Gestion de l'ordre des documents if(model.getOrdreDocuments()!=null && !model.getOrdreDocuments().isEmpty()) { dossierService.setOrderDocuments(model.getDossier(), model.getOrdreDocuments()); } - - tx.commit(); - } catch (Exception e) { - try { - tx.rollback(); - } catch (SystemException e1) { - log.error("Erreur lors du rollback de la vérification de la requête", e1); - } - log.error(e.getMessage(), e); - return this.handleException(e); - } + return null; + }); // Envoi du dossier dans le workflow this.sendFileInWorkflow(request, model); @@ -177,6 +181,7 @@ public class CreerDossierService { msg.setSeverite("INFO"); res.setMessageRetour(msg); + // TODO - IMPORTANT - CE IF DOIT ÊTRE CONSERVÉ ! // FIXME - Retro-compatibilité - Pour les connecteurs n'utilisant pas les dernières versions du WSDL, comprenant le champ "DossierID" // Pour information - Ce champ a été ajouté en 2013 @@ -187,6 +192,28 @@ public class CreerDossierService { return res; } + private void prepareContent(CreerDossierRequest request, CreerDossieModel model) { + String nomDocPrincipal = this.normalizeName(request, model); + + NodeRef found = fileFolderService.searchSimple(model.getDossier(), nomDocPrincipal); + // ici on doit faire en 2 fois, d'abord la suppression, puis la création + // sinon alfresco va nous dire "hey j'ai déjà ce noeud !" car c'est dans la même transaction + if (found != null) { + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + fileFolderService.delete(found); + // On attend 0.5s le temps que le fichier soit effectivement supprimé... + Thread.sleep(500); + return null; + }); + } + + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + FileInfo fileInfo = fileFolderService.create(model.getDossier(), nomDocPrincipal, ContentModel.TYPE_CONTENT); + model.setMainDoc(fileInfo.getNodeRef()); + return null; + }); + } + private void setTypologyAndContents(CreerDossierRequest request, CreerDossieModel model) throws IOException { log.debug(model.getLoggerPrefix() + " - Préparation du circuit..."); // This defines the final workflow to the folder @@ -240,15 +267,13 @@ public class CreerDossierService { } } - private void createDossier(CreerDossierRequest request, CreerDossieModel model) throws ParseException { + private void createDossier(CreerDossierRequest request, CreerDossieModel model) { Map<QName, Serializable> properties = this.defineProperties(model); log.debug(model.getLoggerPrefix() + " - Creation de dossier..."); // ------------------------------------- Création dossier model.setDossier(dossierService.createDossier(model.getParapheur(), properties)); - dossierService.setDossierPropertiesWithAuditTrail(model.getDossier(), model.getParapheur(), properties, true); model.setId((String) nodeService.getProperty(model.getDossier(), ContentModel.PROP_NAME)); - nodeService.addAspect(model.getDossier(), ParapheurModel.ASPECT_DOSSIER_ORIGINE_WS, null); log.debug(model.getLoggerPrefix() + " - Creation de dossier OK"); } @@ -361,7 +386,6 @@ public class CreerDossierService { try { FileInfo fiAnnexe = fileFolderService.create(model.getDossier(), leDoc.getNom(), ContentModel.TYPE_CONTENT); NodeRef docAnnexeRef = fiAnnexe.getNodeRef(); - Map<String, Serializable> docAnnexe = new HashMap<String, Serializable>(); docAnnexe.put("id", docAnnexeRef.getId()); docAnnexe.put("isMainDocument", Boolean.FALSE); @@ -1121,12 +1145,7 @@ public class CreerDossierService { } } - private void setContent(CreerDossierRequest request, CreerDossieModel model) throws IOException { - /* - * Pour éviter les doublons de nommage, on va se souvenir - * des noms de documents déjà fournis et renommer les - * nouveaux. - */ + private String normalizeName(CreerDossierRequest request, CreerDossieModel model) { String nomDocPrincipal; String lContentType = request.getDocumentPrincipal().getContentType().trim().toLowerCase(); @@ -1139,16 +1158,21 @@ public class CreerDossierService { if (log.isDebugEnabled()) { log.debug(model.getLoggerPrefix() + "nom DocPrincipal retenu = " + nomDocPrincipal); } + return nomDocPrincipal; + } - NodeRef found = fileFolderService.searchSimple(model.getDossier(), nomDocPrincipal); - if (found != null) fileFolderService.delete(found); + private void setContent(CreerDossierRequest request, CreerDossieModel model) throws IOException { + /* + * Pour éviter les doublons de nommage, on va se souvenir + * des noms de documents déjà fournis et renommer les + * nouveaux. + */ + String nomDocPrincipal = this.normalizeName(request, model); + String lContentType = request.getDocumentPrincipal().getContentType().trim().toLowerCase(); - FileInfo fileInfo = fileFolderService.create(model.getDossier(), nomDocPrincipal, ContentModel.TYPE_CONTENT); - model.setMainDoc(fileInfo.getNodeRef()); - // Mémorisation document principal Map<String, Serializable> docPrincipal = new HashMap<String, Serializable>(); - docPrincipal.put("id", fileInfo.getNodeRef().getId()); + docPrincipal.put("id", model.getMainDoc().getId()); docPrincipal.put("isMainDocument", Boolean.TRUE); if(model.getOrdreDocuments()==null) { model.setOrdreDocuments(new ArrayList<>()); @@ -1469,7 +1493,7 @@ public class CreerDossierService { model.setWorkflow(workflow); } - private Map<QName, Serializable> defineProperties(CreerDossieModel model) throws ParseException { + private Map<QName, Serializable> defineProperties(CreerDossieModel model) { Map<QName, Serializable> properties = new HashMap<>(); /* @@ -1492,7 +1516,11 @@ public class CreerDossierService { // date Limite if (model.getDateLimite() != null && !model.getDateLimite().trim().isEmpty()) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - properties.put(ParapheurModel.PROP_DATE_LIMITE, dateFormat.parse(model.getDateLimite().trim())); + try { + properties.put(ParapheurModel.PROP_DATE_LIMITE, dateFormat.parse(model.getDateLimite().trim())); + } catch(ParseException e) { + log.error(e.getMessage()); + } } // Visibilite if (model.getVisibilite() != null && !model.getVisibilite().toString().isEmpty()) { @@ -1510,6 +1538,7 @@ public class CreerDossierService { // Type et Sous-type properties.put(ParapheurModel.PROP_TYPE_METIER, model.getType()); properties.put(ParapheurModel.PROP_SOUSTYPE_METIER, model.getSousType()); + properties.put(ParapheurModel.PROP_FULL_CREATED, true); return properties; } @@ -1543,11 +1572,7 @@ public class CreerDossierService { } private void checkRequestWithTypology(CreerDossierRequest request) throws Exception { - RetryingTransactionHelper rtxType = transactionService.getRetryingTransactionHelper(); - // Peut gérer plus de 10 créations simultanées - rtxType.setMaxRetries(10); - rtxType.setReadOnly(true); - Map<String, List<String>> typologie = rtxType.doInTransaction(() -> typesService.optimizedGetSavedType(false, null), true, false); + Map<String, List<String>> typologie = typesService.optimizedGetSavedType(false, null); if (!(typologie.containsKey(request.getTypeTechnique()) && typologie.get(request.getTypeTechnique()).contains(request.getSousType()))) { diff --git a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/amq/impl/MessageSenderImpl.java b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/amq/impl/MessageSenderImpl.java index 760fae90753f32b75d7d0018543cfc0c11ad1602..ab64e489afea7e58e70bc5b0e177fe98fd4d1bec 100644 --- a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/amq/impl/MessageSenderImpl.java +++ b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/amq/impl/MessageSenderImpl.java @@ -41,27 +41,23 @@ public class MessageSenderImpl implements MessagesSender { if(!nodeService.hasAspect(nodeRef, ParapheurModel.ASPECT_PENDING)) { QueueSender sender = activeMQConnectionService.getSender(); //Si la connexion est possible, envoi du JSON dans la MQ, sinon on pose le flag - UserTransaction ut = transactionService.getNonPropagatingUserTransaction(); - try { - ut.begin(); + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { Map<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(ParapheurModel.PROP_LOCKED, true); nodeService.addAspect(nodeRef, ParapheurModel.ASPECT_PENDING, props); - ut.commit(); + return null; + }); + try { TextMessage m = activeMQConnectionService.createTextMessage(); m.setText(objString); logger.info("-----Sending message : " + m.getText()); sender.send(m); } catch (JMSException e) { logger.error("Exception when sending message to activemq : " + e.getMessage()); - nodeService.removeAspect(nodeRef, ParapheurModel.ASPECT_PENDING); - } catch (Exception e2) { - logger.error("Exception when sending message to activemq : " + e2.getMessage()); - try { - ut.rollback(); - } catch(Exception e3) { - logger.error("Exception when rollback after sending message to activemq : " + e3.getMessage()); - } + transactionService.getRetryingTransactionHelper().doInTransaction(() -> { + nodeService.removeAspect(nodeRef, ParapheurModel.ASPECT_PENDING); + return null; + }); } } } diff --git a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/jscript/DossierServiceScriptable.java b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/jscript/DossierServiceScriptable.java index c81c5ce99fed733c55e07813ffb5b243f22772ce..a116aacaa886943b9be4e4eca68a334ebd9a6967 100644 --- a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/jscript/DossierServiceScriptable.java +++ b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/jscript/DossierServiceScriptable.java @@ -141,9 +141,13 @@ public class DossierServiceScriptable extends BaseProcessorExtension { public String beginCreateDossier(String bureauRefStr) { String retVal = null; - NodeRef dossierRef = dossierService.beginCreateDossier(new NodeRef("workspace://SpacesStore/" + bureauRefStr)); - if (dossierRef != null) { - retVal = dossierRef.getId(); + try { + NodeRef dossierRef = dossierService.beginCreateDossier(new NodeRef("workspace://SpacesStore/" + bureauRefStr)); + if (dossierRef != null) { + retVal = dossierRef.getId(); + } + } catch(Exception e) { + e.printStackTrace(); } return retVal; } @@ -160,7 +164,8 @@ public class DossierServiceScriptable extends BaseProcessorExtension { (parapheurService.isParapheurSecretaire(bureauRef, username) && nodeService.hasAspect(dossierRef, ParapheurModel.ASPECT_SECRETARIAT))) { Map<String, Serializable> properties = NativeUtils.nativeToProperties(object); - if (!(Boolean) nodeService.getProperty(dossierRef, ParapheurModel.PROP_FULL_CREATED)) { + Object fullCreated = nodeService.getProperty(dossierRef, ParapheurModel.PROP_FULL_CREATED); + if (fullCreated == null || !(Boolean) fullCreated) { Map<QName, Serializable> baseProperties = new HashMap<>(); for (Map.Entry entry : properties.entrySet()) { baseProperties.put(QName.createQName((String) entry.getKey(), namespaceService), (Serializable) entry.getValue()); diff --git a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/worker/impl/WorkerServiceImpl.java b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/worker/impl/WorkerServiceImpl.java index b117a553c69465f7bdb65b5fe27762d5eec9c714..67e08c3b2bedab01e2c632d84a6eaf7b2f117f0f 100644 --- a/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/worker/impl/WorkerServiceImpl.java +++ b/iparapheur-core/src/main/java/org/adullact/iparapheur/repo/worker/impl/WorkerServiceImpl.java @@ -1386,10 +1386,7 @@ public class WorkerServiceImpl implements WorkerService { boolean error = false; NodeRef node = null, bureauCourant = null; - UserTransaction utx = transactionService.getNonPropagatingUserTransaction(); try { - utx.begin(); - if(request.containsKey(USERNAME)) { final String username = (String) request.get(USERNAME); AuthenticationUtil.setRunAsUser(username); @@ -1418,7 +1415,7 @@ public class WorkerServiceImpl implements WorkerService { public Boolean execute() throws Throwable { return function.execute(); } - }, false, true); + }); function.internSuccess(); } @@ -1426,8 +1423,6 @@ public class WorkerServiceImpl implements WorkerService { logger.error(function.errorMsg); function.error(); } - - utx.commit(); } catch (Exception e) { error = true; @@ -1443,11 +1438,6 @@ public class WorkerServiceImpl implements WorkerService { e.printStackTrace(); } function.error(); - try { - utx.rollback(); - } catch (Exception e1) { - e1.printStackTrace(); - } } finally { // Si il y a eu une exception, le dossier est toujours "PENDING", il faut donc enlever l'aspect pour // ne pas bloquer le dossier. Cependant le removeAspect doit se faire dans une transaction. diff --git a/iparapheur-core/src/main/java/org/adullact/iparapheur/ws/security/X509AndBasicAuthenticationProcessingFilter.java b/iparapheur-core/src/main/java/org/adullact/iparapheur/ws/security/X509AndBasicAuthenticationProcessingFilter.java index 10967b82d4c59dd3d813992a2fcb3efd9b07272b..84ca147705be1ede869f8c549ad97949b9e5df58 100644 --- a/iparapheur-core/src/main/java/org/adullact/iparapheur/ws/security/X509AndBasicAuthenticationProcessingFilter.java +++ b/iparapheur-core/src/main/java/org/adullact/iparapheur/ws/security/X509AndBasicAuthenticationProcessingFilter.java @@ -41,24 +41,9 @@ */ package org.adullact.iparapheur.ws.security; -import java.io.IOException; -import java.security.cert.X509Certificate; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.UserTransaction; - -import net.sf.acegisecurity.Authentication; -import net.sf.acegisecurity.AuthenticationException; -import net.sf.acegisecurity.AuthenticationManager; -import net.sf.acegisecurity.BadCredentialsException; -import net.sf.acegisecurity.UserDetails; +import lombok.Getter; +import lombok.Setter; +import net.sf.acegisecurity.*; import net.sf.acegisecurity.context.security.SecureContextUtils; import net.sf.acegisecurity.intercept.web.AuthenticationEntryPoint; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; @@ -72,36 +57,32 @@ import org.alfresco.service.transaction.TransactionService; import org.alfresco.web.app.servlet.AbstractAuthenticationFilter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.oro.text.regex.MalformedPatternException; -import org.apache.oro.text.regex.MatchResult; -import org.apache.oro.text.regex.Pattern; -import org.apache.oro.text.regex.PatternMatcher; -import org.apache.oro.text.regex.Perl5Compiler; -import org.apache.oro.text.regex.Perl5Matcher; +import org.apache.oro.text.regex.*; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.extensions.surf.util.Base64; import org.springframework.util.Assert; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.security.cert.X509Certificate; + /** * Filtre d'authentification prenant en compte deux methodes: authentification * basique (obligatoire) + authentification par certificat client. * L'authentification resultante est la concatenation de l'identite extraite du - * certificat et du nom d'utilisateur passe en authentification basique. + * certificat et du nom d'utilisateur passe en authentification basique. * Voir setDealWithCertificate, setX509SubjectDNRegex, setTokenSeparator... - * + * * @author Emmanuel Delmasure - Berger Levrault * @author Stepahne Vast - Adullact Projet */ -public class X509AndBasicAuthenticationProcessingFilter extends AbstractAuthenticationFilter implements Filter, InitializingBean, ApplicationEventPublisherAware -{ - class X509AndBasicAuthenticationException extends AuthenticationException { - private static final long serialVersionUID = 1L; - public X509AndBasicAuthenticationException(String msg) { - super(msg); - } - } +@Getter +@Setter +public class X509AndBasicAuthenticationProcessingFilter extends AbstractAuthenticationFilter implements Filter, InitializingBean, ApplicationEventPublisherAware { private static final Log logger = LogFactory.getLog(X509AndBasicAuthenticationProcessingFilter.class); private ApplicationEventPublisher eventPublisher; private AuthenticationManager authenticationManager; @@ -115,263 +96,128 @@ public class X509AndBasicAuthenticationProcessingFilter extends AbstractAuthenti private Pattern subjectDNPattern; private boolean dealWithCertificate = true; - public boolean isDealWithCertificate() - { - return dealWithCertificate; - } - - /** - * Definit si il faut tenir compte du nom issu du certificat pour la construction du nom d'utilisateur. - * - * @param dealWithCertificate - */ - public void setDealWithCertificate(boolean dealWithCertificate) - { - this.dealWithCertificate = dealWithCertificate; - } - - public String getX509SubjectDNRegex() - { - return x509SubjectDNRegex; - } - - /** - * Definit l'expression reguliere a appliquer a la chaine du certificat pour - * en extraire une identite. - * - * @param subjectDNRegex - */ - public void setX509SubjectDNRegex(String subjectDNRegex) - { - x509SubjectDNRegex = subjectDNRegex; - } - - public String getTokenSeparator() - { - return tokenSeparator; - } - - /** - * Definit le separateur a utiliser pour construire le nom d'utilisateur resultant de la concatenation de - * l'identite du certificat et du nom d'utilisateur passe par l'authentification basique. - * - * @param tokenSeparator - */ - public void setTokenSeparator(String tokenSeparator) - { - this.tokenSeparator = tokenSeparator; - } - - public boolean isIgnoreFailure() - { - return ignoreFailure; + public void destroy() { } - public void setIgnoreFailure(boolean ignoreFailure) - { - this.ignoreFailure = ignoreFailure; - } - - public AuthenticationEntryPoint getBasicAuthenticationEntryPoint() - { - return basicAuthenticationEntryPoint; - } - - public void setBasicAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) - { - this.basicAuthenticationEntryPoint = authenticationEntryPoint; - } - - public RememberMeServices getRememberMeServices() - { - return rememberMeServices; - } - - public void setRememberMeServices(RememberMeServices rememberMeServices) - { - this.rememberMeServices = rememberMeServices; - } + public void afterPropertiesSet() throws Exception { + Assert.notNull(authenticationManager, "An AuthenticationManager must be set"); + Assert.notNull(authenticationComponent, "An AuthenticationComponent must be set"); + Assert.notNull(transactionService, "There must be a transaction service"); - public void destroy() - { - } + if (dealWithCertificate) { + Perl5Compiler compiler = new Perl5Compiler(); - public void afterPropertiesSet() throws Exception - { - Assert.notNull(authenticationManager, "An AuthenticationManager must be set"); - Assert.notNull(authenticationComponent, "An AuthenticationComponent must be set"); - Assert.notNull(transactionService, "There must be a transaction service"); - - if (dealWithCertificate) - { - Perl5Compiler compiler = new Perl5Compiler(); - - try - { - subjectDNPattern = compiler.compile(x509SubjectDNRegex, Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK); - } catch (MalformedPatternException mpe) - { - throw new IllegalArgumentException("Malformed regular expression: " + x509SubjectDNRegex); - } - } + try { + subjectDNPattern = compiler.compile(x509SubjectDNRegex, Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK); + } catch (MalformedPatternException mpe) { + throw new IllegalArgumentException("Malformed regular expression: " + x509SubjectDNRegex); + } + } } - private String extractUserNameFromX509Certificate(X509Certificate clientCert) throws AuthenticationException - { - String subjectDN = clientCert.getSubjectDN().getName(); - PatternMatcher matcher = new Perl5Matcher(); - if (!matcher.contains(subjectDN, subjectDNPattern)) - { - throw new BadCredentialsException("DaoX509AuthoritiesPopulator.noMatching: no matching pattern was found in subjectDN: {0}"); - } - MatchResult match = matcher.getMatch(); - if (match.groups() != 2) - { // 2 = 1 + the entire match - throw new IllegalArgumentException("Regular expression must contain a single group "); - } - String userName = match.group(1); - return userName; + private String extractUserNameFromX509Certificate(X509Certificate clientCert) throws AuthenticationException { + String subjectDN = clientCert.getSubjectDN().getName(); + PatternMatcher matcher = new Perl5Matcher(); + if (!matcher.contains(subjectDN, subjectDNPattern)) { + throw new BadCredentialsException("DaoX509AuthoritiesPopulator.noMatching: no matching pattern was found in subjectDN: {0}"); + } + MatchResult match = matcher.getMatch(); + if (match.groups() != 2) { // 2 = 1 + the entire match + throw new IllegalArgumentException("Regular expression must contain a single group "); + } + return match.group(1); } @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException - { - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; - - if (!(request instanceof HttpServletRequest)) - { - throw new ServletException("Can only process HttpServletRequest"); - } - - if (!(response instanceof HttpServletResponse)) - { - throw new ServletException("Can only process HttpServletResponse"); - } - - String header = httpRequest.getHeader("Authorization"); - - if (logger.isInfoEnabled()) - logger.info("Authorization header: " + header); - - if (header == null || !header.startsWith("Basic ")) - { - basicAuthenticationEntryPoint.commence(request, response, new X509AndBasicAuthenticationException("No authorization header, asking for one...")); - return; - } else { - if (SecureContextUtils.getSecureContext().getAuthentication() == null) - { - String username = ""; - if (dealWithCertificate) - { - X509Certificate clientCertificate = extractClientCertificate(httpRequest); - username = extractUserNameFromX509Certificate(clientCertificate) + getTokenSeparator(); - } - String base64Token = header.substring(6); - // if (logger.isDebugEnabled()) logger.debug(" base64Token=" + base64Token); - - String token = new String(Base64.decode(base64Token)); - // if (logger.isDebugEnabled()) logger.debug(" token=" + token); - - String password = ""; - int delim = token.indexOf(":"); - - if (delim != -1) { - username += token.substring(0, delim); - password = token.substring(delim + 1); - } - - if (authenticationIsRequired(username)) { - UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); - authRequest.setDetails(new WebAuthenticationDetails((HttpServletRequest) request)); - if (logger.isDebugEnabled()) - logger.debug(" username=" + username + " password=" + password); + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + if (request == null) { + throw new ServletException("Can only process HttpServletRequest"); + } + + if (response == null) { + throw new ServletException("Can only process HttpServletResponse"); + } + + String header = httpRequest.getHeader("Authorization"); + + if (logger.isInfoEnabled()) + logger.info("Authorization header: " + header); + + if (header == null || !header.startsWith("Basic ")) { + basicAuthenticationEntryPoint.commence(request, response, new X509AndBasicAuthenticationException("No authorization header, asking for one...")); + return; + } else { + if (SecureContextUtils.getSecureContext().getAuthentication() == null) { + String username = ""; + if (dealWithCertificate) { + X509Certificate clientCertificate = extractClientCertificate(httpRequest); + if(clientCertificate != null) { + username = extractUserNameFromX509Certificate(clientCertificate) + getTokenSeparator(); + } + } + String base64Token = header.substring(6); + // if (logger.isDebugEnabled()) logger.debug(" base64Token=" + base64Token); + + String token = new String(Base64.decode(base64Token)); + // if (logger.isDebugEnabled()) logger.debug(" token=" + token); + + String password = ""; + int delim = token.indexOf(":"); + + if (delim != -1) { + username += token.substring(0, delim); + password = token.substring(delim + 1); + } + + if (authenticationIsRequired(username)) { + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); + authRequest.setDetails(new WebAuthenticationDetails((HttpServletRequest) request)); + if (logger.isDebugEnabled()) + logger.debug(" username=" + username + " password=" + password); // Authentication authResult; - UserTransaction tx = transactionService.getNonPropagatingUserTransaction(); - try { - tx.begin(); + try { // authResult = authenticationManager.authenticate(authRequest); authenticationComponent.authenticate(username, password.toCharArray()); - tx.commit(); - } catch (AuthenticationException failed) - { - try - { - if (tx.getStatus() == javax.transaction.Status.STATUS_ACTIVE) { - tx.rollback(); - } - } - catch (Exception ex2) - { - logger.error("Failed to rollback transaction", ex2); - } - // Authentication failed - if (logger.isDebugEnabled()) { - logger.debug("Authentication request for user: " + username + " failed: " + failed.toString()); - } - - SecureContextUtils.getSecureContext().setAuthentication(null); - - if (rememberMeServices != null) { - rememberMeServices.loginFail(httpRequest, httpResponse); - } - - if (ignoreFailure) { - chain.doFilter(request, response); - } else { - basicAuthenticationEntryPoint.commence(request, response, failed); - } - - return; - } - catch (org.alfresco.repo.security.authentication.AuthenticationException ex) { - - try - { - if (tx.getStatus() == javax.transaction.Status.STATUS_ACTIVE) { - tx.rollback(); - } - } - catch (Exception ex2) - { - logger.error("Failed to rollback transaction", ex2); - } - + } catch (AuthenticationException failed) { + // Authentication failed + if (logger.isDebugEnabled()) { + logger.debug("Authentication request for user: " + username + " failed: " + failed); + } + + SecureContextUtils.getSecureContext().setAuthentication(null); + + if (rememberMeServices != null) { + rememberMeServices.loginFail(httpRequest, httpResponse); + } + + if (ignoreFailure) { + chain.doFilter(request, response); + } else { + basicAuthenticationEntryPoint.commence(request, response, failed); + } + + return; + } catch (org.alfresco.repo.security.authentication.AuthenticationException ex) { chain.doFilter(request, response); return; + } catch (Throwable ex) { + if (ex instanceof AuthenticationException) { + logger.error("Impossible d'authentifier l'utisateur"); + throw new RuntimeException("Utilisateur inconnu", ex); + } else if (ex instanceof RuntimeException) { + logger.error(ex); + throw (RuntimeException) ex; + } else { + logger.error(ex); + throw new RuntimeException("Failed to set authenticated user", ex); + } } - catch (Throwable ex) - { - try - { - if (tx.getStatus() == javax.transaction.Status.STATUS_ACTIVE) { - tx.rollback(); - } - } - catch (Exception ex2) - { - logger.error("Failed to rollback transaction", ex2); - } - - if(ex instanceof AuthenticationException) - { - logger.error("Impossible d'authentifier l'utisateur"); - throw new RuntimeException("Utilisateur inconnu", ex); - } - else if(ex instanceof RuntimeException) - { - logger.error(ex); - throw (RuntimeException)ex; - } - else - { - logger.error(ex); - throw new RuntimeException("Failed to set authenticated user", ex); - } - } - - // Authentication success + + // Authentication success // if (logger.isInfoEnabled()) // logger.info(username + " ("+password+"), from "+authResult.getDetails().toString()); // if (logger.isDebugEnabled()) @@ -383,134 +229,105 @@ public class X509AndBasicAuthenticationProcessingFilter extends AbstractAuthenti // if (rememberMeServices != null) { // rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult); // } - } - } + } + } - } - chain.doFilter(request, response); + } + chain.doFilter(request, response); } - /** * Puts the <code>Authentication</code> instance returned by the authentication manager into the secure context. - * - * @param request DOCUMENT ME! - * @param response DOCUMENT ME! - * @param authResult DOCUMENT ME! - * + * + * @param request DOCUMENT ME! + * @param response DOCUMENT ME! + * @param authResult DOCUMENT ME! * @throws IOException DOCUMENT ME! */ - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException - { - if (logger.isDebugEnabled()) - logger.debug("[successfulAuthentication]Authentication success: " + authResult); - - SecureContextUtils.getSecureContext().setAuthentication(authResult); - - // Fire event - if (this.eventPublisher != null) - { - eventPublisher.publishEvent(new AuthenticationSuccessEvent(authResult, (UserDetails) authResult.getDetails())); - } + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException { + if (logger.isDebugEnabled()) + logger.debug("[successfulAuthentication]Authentication success: " + authResult); + + SecureContextUtils.getSecureContext().setAuthentication(authResult); + + // Fire event + if (this.eventPublisher != null) { + eventPublisher.publishEvent(new AuthenticationSuccessEvent(authResult, (UserDetails) authResult.getDetails())); + } } /** * Ensures the authentication object in the secure context is set to null when authentication fails. - * + * * @param request DOCUMENT ME! * @param response DOCUMENT ME! * @param failed DOCUMENT ME! */ - protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) - { - SecureContextUtils.getSecureContext().setAuthentication(null); + protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) { + SecureContextUtils.getSecureContext().setAuthentication(null); - if (logger.isDebugEnabled()) - logger.debug("Updated SecurityContextHolder to contain null Authentication"); + if (logger.isDebugEnabled()) + logger.debug("Updated SecurityContextHolder to contain null Authentication"); - request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed); + request.getSession().setAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed); } - public AuthenticationManager getAuthenticationManager() - { - return authenticationManager; + private boolean authenticationIsRequired(String username) { + // Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated + // (see SEC-53) + Authentication existingAuth = SecureContextUtils.getSecureContext().getAuthentication(); + + if (existingAuth == null || !existingAuth.isAuthenticated()) { + return true; + } + + // Limit username comparison to providers which use usernames (ie UsernamePasswordAuthenticationToken) + // (see SEC-348) + if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) { + return true; + } + + // Handle unusual condition where an AnonymousAuthenticationToken is already present + // This shouldn't happen very often, as BasicProcessingFitler is meant to be earlier in the filter + // chain than AnonymousProcessingFilter. Nevertheless, presence of both an AnonymousAuthenticationToken + // together with a BASIC authentication request header should indicate reauthentication using the + // BASIC protocol is desirable. This behavior is also consistent with that provided by form and digest, + // both of which force re-authentication if the respective header is detected (and in doing so replace + // any existing AnonymousAuthenticationToken). See SEC-610. + if (existingAuth instanceof AnonymousAuthenticationToken) { + return true; + } + + return false; } - public void setAuthenticationManager(AuthenticationManager authenticationManager) - { - this.authenticationManager = authenticationManager; - } + private X509Certificate extractClientCertificate(HttpServletRequest request) { + X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); - public TransactionService gettransactionService() - { - return transactionService; - } + if ((certs != null) && (certs.length > 0)) { + return certs[0]; + } - public AuthenticationComponent getAuthenticationComponent() { - return authenticationComponent; - } + if (logger.isDebugEnabled()) { + logger.debug("No client certificate found in request."); + } - public void setAuthenticationComponent(AuthenticationComponent authenticationComponent) { - this.authenticationComponent = authenticationComponent; + return null; } - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; + public void init(FilterConfig ignored) throws ServletException { } - private boolean authenticationIsRequired(String username) - { - // Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated - // (see SEC-53) - Authentication existingAuth = SecureContextUtils.getSecureContext().getAuthentication(); - - if (existingAuth == null || !existingAuth.isAuthenticated()) { - return true; - } - - // Limit username comparison to providers which use usernames (ie UsernamePasswordAuthenticationToken) - // (see SEC-348) - if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) { - return true; - } - - // Handle unusual condition where an AnonymousAuthenticationToken is already present - // This shouldn't happen very often, as BasicProcessingFitler is meant to be earlier in the filter - // chain than AnonymousProcessingFilter. Nevertheless, presence of both an AnonymousAuthenticationToken - // together with a BASIC authentication request header should indicate reauthentication using the - // BASIC protocol is desirable. This behavior is also consistent with that provided by form and digest, - // both of which force re-authentication if the respective header is detected (and in doing so replace - // any existing AnonymousAuthenticationToken). See SEC-610. - if (existingAuth instanceof AnonymousAuthenticationToken) { - return true; - } - - return false; + public void setApplicationEventPublisher(ApplicationEventPublisher context) { + this.eventPublisher = context; } - private X509Certificate extractClientCertificate(HttpServletRequest request) - { - X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); - - if ((certs != null) && (certs.length > 0)) { - return certs[0]; - } - - if (logger.isDebugEnabled()) { - logger.debug("No client certificate found in request."); - } - - return null; - } - - public void init(FilterConfig ignored) throws ServletException - { - } + class X509AndBasicAuthenticationException extends AuthenticationException { + private static final long serialVersionUID = 1L; - public void setApplicationEventPublisher(ApplicationEventPublisher context) - { - this.eventPublisher = context; + public X509AndBasicAuthenticationException(String msg) { + super(msg); + } } } diff --git a/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheur-version.properties b/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheur-version.properties index cef2a6cf71526608e3a1c40b34f7c2766b4df6f2..7940c8f492870d633916354c688ab47bf93e9b9e 100755 --- a/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheur-version.properties +++ b/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheur-version.properties @@ -1,2 +1,2 @@ -ph_version=4.7.25 +ph_version=4.7.26-rc.1 ph_build=20250130 diff --git a/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheurModel.xml b/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheurModel.xml index 454bb2a7b2cad83ab556ccd73f17f8c5f000c417..f97d266ad3f254e23ff7b1facdbbc175afe78dcf 100755 --- a/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheurModel.xml +++ b/iparapheur-core/src/main/resources/alfresco/module/parapheur/core/parapheurModel.xml @@ -128,6 +128,11 @@ <title>Inclure les pièces jointes lors de l'impression/archivage</title> <type>d:boolean</type> </property> + <property name="ph:dossier-created"> + <title>Le dossier est il entier</title> + <type>d:boolean</type> + </property> + <property name="ph:lecteurs"> <title>Lecteurs du dossier pour l'étape courante</title> <type>d:text</type> diff --git a/iparapheur-mobile-webscripts/pom.xml b/iparapheur-mobile-webscripts/pom.xml index bf2fb40c4f3951bc6003b0e15a166b4313d86c01..287bb9cd342790ba53186b77c32de00e4339bc78 100644 --- a/iparapheur-mobile-webscripts/pom.xml +++ b/iparapheur-mobile-webscripts/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>iparapheur</artifactId> <groupId>org.adullact.iparapheur</groupId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </parent> <modelVersion>4.0.0</modelVersion> @@ -94,7 +94,7 @@ <dependency> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur-core</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> <scope>provided</scope> </dependency> diff --git a/iparapheur-rules/pom.xml b/iparapheur-rules/pom.xml index e2fc36fda0d7ad1fc028841ac893cbaa74e910e4..60a6811ba95522e6b94baaf3581e287d39c60977 100644 --- a/iparapheur-rules/pom.xml +++ b/iparapheur-rules/pom.xml @@ -5,10 +5,10 @@ <parent> <groupId>org.adullact.iparapheur</groupId> <artifactId>iparapheur</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> </parent> <artifactId>iparapheur-rules</artifactId> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> <name>iparapheur-rules</name> <url>http://maven.apache.org</url> <properties> diff --git a/pom.xml b/pom.xml index eb6bb51adc2c6cebe60ff46ee609d050defe4a58..a45837912dfef42de3ffae4d6697b41ba53bc440 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <artifactId>iparapheur</artifactId> <packaging>pom</packaging> <name>iparapheur</name> - <version>4.7.25</version> + <version>4.7.26-rc.1</version> <description>Parapheur electronique</description> <url>https://adullact.net/projects/paraphelec/</url>