Autre fonctionnalité liée au format PDF pouvant s’avérer intéressante : la protection d’un fichier par un mot de passe, ainsi que la restriction des actions autorisées (extraction de texte, impression, …). L’implémentation va encore une fois se faire par le biais d’une action Alfresco, mais utilisera la librairie PDFBox, embarquée par Alfresco.
PDFBox [en] est une librairie Java Open-Source (licence BSD) permettant de travailler avec des fichiers PDF (génération, modification et extraction de contenu). Elle comporte également plusieurs programmes utilisables en ligne de commande.
# Détails de l’action
Pour cette action de protection, il va nous falloir comme paramètres :
- les mots de passe propriétaire et utilisateur du document,
- le détail des actions autorisées.
Dans PDFBox, ce type de protection est représenté par les objets ProtectionPolicy (pour la partie authentification) et AccessPermission (pour la partie détail); plus précisément nous utiliserons une StandardProtectionPolicy, une protection par mot de passe (par opposition à la PublicKeyProtectionPolicy, protection par certificat).
Notre action va donc ouvrir le document PDF, vérifier si il n’est pas déjà protégé, puis créer la protection à partir des paramètres utilisateurs et enfin l’appliquer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
package com.atolcd.repo.action.executer; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.executer.ActionExecuterAbstractBase; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.util.TempFileProvider; import org.pdfbox.exceptions.COSVisitorException; import org.pdfbox.pdmodel.PDDocument; import org.pdfbox.pdmodel.encryption.AccessPermission; import org.pdfbox.pdmodel.encryption.BadSecurityHandlerException; import org.pdfbox.pdmodel.encryption.StandardProtectionPolicy; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; public class PDFProtectActionExecuter extends ActionExecuterAbstractBase implements InitializingBean { public static final String NAME = "protect"; public final static String PARAM_OWNER_PASSWORD = "owner_password"; public final static String PARAM_USER_PASSWORD = "user_password"; public final static String PARAM_ASSEMBLY = "assembly"; public final static String PARAM_EXTRACT_CONTENT = "extract_content"; public final static String PARAM_EXTRACT_ACCESSIBILITY = "extract_accessibility"; public final static String PARAM_FILLING = "filling"; public final static String PARAM_MODIFY = "modify"; public final static String PARAM_MODIFY_ANNOTATIONS = "modify_annotations"; public final static String PARAM_PRINTING = "printing"; public final static String PARAM_DEGRADED_PRINTING = "degraded_printing"; private ContentService contentService; public void afterPropertiesSet() throws Exception { Assert.notNull(contentService); } public void setContentService(ContentService contentService) { this.contentService = contentService; } @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { ContentReader reader = contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT); if (MimetypeMap.MIMETYPE_PDF.equals(reader.getMimetype())) { PDDocument doc = null; try { File newPdf = TempFileProvider.createTempFile("tmp", "protect"); FileOutputStream fos = new FileOutputStream(newPdf); doc = PDDocument.load(reader.getContentInputStream()); if (!doc.isEncrypted()) { Boolean allowAssembly = (Boolean) action .getParameterValue(PARAM_ASSEMBLY); Boolean allowExtraction = (Boolean) action .getParameterValue(PARAM_EXTRACT_CONTENT); Boolean allowExtractionAccessibility = (Boolean) action .getParameterValue(PARAM_EXTRACT_ACCESSIBILITY); Boolean allowFillingInForm = (Boolean) action .getParameterValue(PARAM_FILLING); Boolean allowModifications = (Boolean) action .getParameterValue(PARAM_MODIFY); Boolean allowAnnotationModification = (Boolean) action .getParameterValue(PARAM_MODIFY_ANNOTATIONS); Boolean allowPrinting = (Boolean) action .getParameterValue(PARAM_PRINTING); Boolean allowDegradedPrinting = (Boolean) action .getParameterValue(PARAM_DEGRADED_PRINTING); AccessPermission ap = new AccessPermission(); ap .setCanAssembleDocument((allowAssembly != null && allowAssembly .booleanValue())); ap .setCanExtractContent((allowExtraction != null && allowExtraction .booleanValue())); ap .setCanExtractForAccessibility((allowExtractionAccessibility != null && allowExtractionAccessibility .booleanValue())); ap .setCanFillInForm((allowFillingInForm != null && allowFillingInForm .booleanValue())); ap .setCanModify((allowModifications != null && allowModifications .booleanValue())); ap .setCanModifyAnnotations((allowAnnotationModification != null && allowAnnotationModification .booleanValue())); ap.setCanPrint((allowPrinting != null && allowPrinting .booleanValue())); ap .setCanPrintDegraded((allowDegradedPrinting != null && allowDegradedPrinting .booleanValue())); StandardProtectionPolicy policy = new StandardProtectionPolicy( (String) action .getParameterValue(PARAM_OWNER_PASSWORD), (String) action .getParameterValue(PARAM_USER_PASSWORD), ap); doc.protect(policy); doc.save(fos); fos.close(); doc.close(); ContentWriter writer = contentService.getWriter( actionedUponNodeRef, ContentModel.PROP_CONTENT, true); writer.putContent(newPdf); } else { doc.close(); throw new RuntimeException( "This document is already encrypted"); } } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch (BadSecurityHandlerException bshe) { bshe.printStackTrace(); } catch (COSVisitorException cosve) { cosve.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } } } @Override protected void addParameterDefinitions(List paramList) { paramList.add(new ParameterDefinitionImpl(PARAM_OWNER_PASSWORD, DataTypeDefinition.TEXT, true, getParamDisplayLabel(PARAM_OWNER_PASSWORD))); paramList.add(new ParameterDefinitionImpl(PARAM_USER_PASSWORD, DataTypeDefinition.TEXT, true, getParamDisplayLabel(PARAM_USER_PASSWORD))); paramList.add(new ParameterDefinitionImpl(PARAM_ASSEMBLY, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_ASSEMBLY))); paramList.add(new ParameterDefinitionImpl(PARAM_EXTRACT_CONTENT, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_EXTRACT_CONTENT))); paramList.add(new ParameterDefinitionImpl(PARAM_EXTRACT_ACCESSIBILITY, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_EXTRACT_ACCESSIBILITY))); paramList.add(new ParameterDefinitionImpl(PARAM_FILLING, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_FILLING))); paramList.add(new ParameterDefinitionImpl(PARAM_MODIFY, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_MODIFY))); paramList.add(new ParameterDefinitionImpl(PARAM_MODIFY_ANNOTATIONS, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_MODIFY_ANNOTATIONS))); paramList.add(new ParameterDefinitionImpl(PARAM_PRINTING, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_PRINTING))); paramList.add(new ParameterDefinitionImpl(PARAM_DEGRADED_PRINTING, DataTypeDefinition.BOOLEAN, false, getParamDisplayLabel(PARAM_DEGRADED_PRINTING))); } } |
# Module
Encore une fois, nous vous proposons ici l’action sous la forme d’un module Alfresco, les sources complètes étant disponibles ici.
Laisser un commentaire