/** * Helper method to set audited information after method invocation and to determine if auditing * should take place based on the method return value. * * @param auditMode * @param auditInfo * @param mi * @param returnObject * @return - the audit mode. */ private AuditMode postInvocation( AuditMode auditMode, AuditState auditInfo, MethodInvocation mi, Object returnObject) { if (returnObject == null) { auditInfo.setReturnObject(null); } else if (returnObject instanceof Serializable) { auditInfo.setReturnObject((Serializable) returnObject); } else { auditInfo.setReturnObject(returnObject.toString()); } Auditable auditable = mi.getMethod().getAnnotation(Auditable.class); if (auditable.key() == Auditable.Key.RETURN) { if (returnObject != null) { if (returnObject instanceof NodeRef) { NodeRef key = (NodeRef) returnObject; auditInfo.setKeyStore(key.getStoreRef()); auditInfo.setKeyGUID(key.getId()); RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi); if (recordOptions != null && recordOptions.getRecordPath() == TrueFalseUnset.TRUE) { auditInfo.setPath(getNodePath(key)); } } else if (returnObject instanceof StoreRef) { auditInfo.setKeyStore((StoreRef) returnObject); } else if (returnObject instanceof ChildAssociationRef) { ChildAssociationRef car = (ChildAssociationRef) returnObject; auditInfo.setKeyStore(car.getChildRef().getStoreRef()); auditInfo.setKeyGUID(car.getChildRef().getId()); RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi); if (recordOptions != null && recordOptions.getRecordPath() == TrueFalseUnset.TRUE) { auditInfo.setPath(nodeService.getPath(car.getChildRef()).toString()); } } else { logger.warn( "Key argument is not a node, store or child assoc ref for return object on " + publicServiceIdentifier.getPublicServiceName(mi) + "." + mi.getMethod().getName() + " it is " + returnObject.getClass().getName()); } } } // If the user name is not set, try and set it after the method call. // This covers authentication when the user is only known after the call. if (auditInfo.getUserIdentifier() == null) { auditInfo.setUserIdentifier(AuthenticationUtil.getFullyAuthenticatedUser()); } return auditMode; }
/* * (non-Javadoc) * * @see org.alfresco.repo.audit.AuditComponent#beforeMethodCallManualAudit(org.aopalliance.intercept.MethodInvocation) */ @SuppressWarnings("unchecked") public void beforeMethodCallManualAudit( Class clazz, Object target, String methodName, Object... args) { Class[] argTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { argTypes[i] = args[i].getClass(); } Method method; try { method = clazz.getMethod(methodName, argTypes); } catch (SecurityException e1) { return; } catch (NoSuchMethodException e1) { return; } MethodInvocation methodInvocation = new ReflectiveMethodInvocation(null, target, method, args, null, null) {}; if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue())) { if (auditModel instanceof AuditEntry && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE) { boolean auditInternal = (auditModel.getAuditInternalServiceMethods(methodInvocation) == TrueFalseUnset.TRUE); try { String serviceName = publicServiceIdentifier.getPublicServiceName(methodInvocation); if (!auditInternal) { auditFlag.set(Boolean.TRUE); } else { if (logger.isDebugEnabled()) { logger.debug( "Auditing internal service use for - " + serviceName + "." + methodName); } } if (method.isAnnotationPresent(Auditable.class)) { if (serviceName != null) { if (logger.isDebugEnabled()) { logger.debug("Auditing - " + serviceName + "." + methodName); } try { auditImpl(methodInvocation, false); } catch (Throwable e) { } } else { if (logger.isDebugEnabled()) { logger.debug("UnknownService." + methodName); } try { auditImpl(methodInvocation, false); } catch (Throwable e) { } } } else if (method.isAnnotationPresent(NotAuditable.class)) { if (logger.isDebugEnabled()) { logger.debug("Not Audited. " + serviceName + "." + methodName); } } else { if (logger.isDebugEnabled()) { logger.debug("Unannotated service method " + serviceName + "." + methodName); } if (method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAnnotationPresent(PublicService.class)) { throw new RuntimeException( "Unannotated service method " + serviceName + "." + methodName); } } } finally { if (!auditInternal) { auditFlag.set(Boolean.FALSE); } } } } }
/** * Set auditable information and determine if auditing is required before method invocation. This * would normally be based on the method arguments. * * @param auditMode * @param auditInfo * @param mi * @return - the audit mode. */ private AuditMode beforeInvocation( AuditMode auditMode, AuditState auditInfo, MethodInvocation mi) { AuditMode effectiveAuditMode = auditModel.beforeExecution(auditMode, mi); if (auditMode != AuditMode.NONE) { String methodName = mi.getMethod().getName(); String serviceName = publicServiceIdentifier.getPublicServiceName(mi); auditInfo.setAuditApplication(SYSTEM_APPLICATION); auditInfo.setAuditConfiguration(auditConfiguration); auditInfo.setAuditMethod(methodName); auditInfo.setAuditService(serviceName); auditInfo.setClientAddress(null); auditInfo.setDate(new Date()); auditInfo.setFail(false); auditInfo.setFiltered(false); auditInfo.setHostAddress(auditHost); auditInfo.setPath(null); Auditable auditable = mi.getMethod().getAnnotation(Auditable.class); Object key = null; switch (auditable.key()) { case ARG_0: checkArgLength(mi, methodName, serviceName, 0); key = mi.getArguments()[0]; break; case ARG_1: checkArgLength(mi, methodName, serviceName, 1); key = mi.getArguments()[1]; break; case ARG_2: checkArgLength(mi, methodName, serviceName, 2); key = mi.getArguments()[2]; break; case ARG_3: checkArgLength(mi, methodName, serviceName, 3); key = mi.getArguments()[3]; break; case ARG_4: checkArgLength(mi, methodName, serviceName, 4); key = mi.getArguments()[4]; break; case ARG_5: checkArgLength(mi, methodName, serviceName, 5); key = mi.getArguments()[5]; break; case ARG_6: checkArgLength(mi, methodName, serviceName, 6); key = mi.getArguments()[6]; break; case ARG_7: checkArgLength(mi, methodName, serviceName, 7); key = mi.getArguments()[7]; break; case ARG_8: checkArgLength(mi, methodName, serviceName, 8); key = mi.getArguments()[8]; break; case ARG_9: checkArgLength(mi, methodName, serviceName, 9); key = mi.getArguments()[9]; break; case NO_KEY: default: break; } if (key != null) { RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi); if (key instanceof NodeRef) { auditInfo.setKeyStore(((NodeRef) key).getStoreRef()); auditInfo.setKeyGUID(((NodeRef) key).getId()); if (recordOptions != null && recordOptions.getRecordPath() == TrueFalseUnset.TRUE) { auditInfo.setPath(getNodePath((NodeRef) key)); } } else if (key instanceof StoreRef) { auditInfo.setKeyStore((StoreRef) key); } else if (key instanceof ChildAssociationRef) { ChildAssociationRef car = (ChildAssociationRef) key; auditInfo.setKeyStore(car.getParentRef().getStoreRef()); auditInfo.setKeyGUID(car.getParentRef().getId()); if (recordOptions != null && recordOptions.getRecordPath() == TrueFalseUnset.TRUE) { auditInfo.setPath(getNodePath(car.getParentRef())); } } else if (key instanceof SearchParameters) { SearchParameters sp = (SearchParameters) key; if (sp.getStores().size() > 0) { auditInfo.setKeyStore(sp.getStores().get(0)); } } else { logger.warn( "Key argument is not a node, store or child assoc reference or search parameters on " + serviceName + "." + methodName + " it is " + key.getClass().getName()); } } auditInfo.setKeyPropertiesAfter(null); auditInfo.setKeyPropertiesBefore(null); auditInfo.setMessage(null); if (mi.getArguments() != null) { Serializable[] serArgs = new Serializable[mi.getArguments().length]; for (int i = 0; i < mi.getArguments().length; i++) { if ((auditable.recordable() == null) || (auditable.recordable().length <= i) || auditable.recordable()[i]) { if (mi.getArguments()[i] == null) { serArgs[i] = null; } else if (mi.getArguments()[i] instanceof Serializable) { serArgs[i] = (Serializable) mi.getArguments()[i]; } else { serArgs[i] = mi.getArguments()[i].toString(); } } else { serArgs[i] = "********"; } } auditInfo.setMethodArguments(serArgs); } auditInfo.setReturnObject(null); auditInfo.setSessionId(null); auditInfo.setThrowable(null); auditInfo.setTxId(AlfrescoTransactionSupport.getTransactionId()); auditInfo.setUserIdentifier(AuthenticationUtil.getFullyAuthenticatedUser()); } return effectiveAuditMode; }
public Object audit(MethodInvocation mi) throws Throwable { if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue())) { if (auditModel instanceof AuditEntry && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE) { boolean auditInternal = (auditModel.getAuditInternalServiceMethods(mi) == TrueFalseUnset.TRUE); try { Method method = mi.getMethod(); String methodName = method.getName(); String serviceName = publicServiceIdentifier.getPublicServiceName(mi); if (!auditInternal) { auditFlag.set(Boolean.TRUE); } else { if (logger.isDebugEnabled()) { logger.debug( "Auditing internal service use for - " + serviceName + "." + methodName); } } if (method.isAnnotationPresent(Auditable.class)) { if (serviceName != null) { if (logger.isDebugEnabled()) { logger.debug("Auditing - " + serviceName + "." + methodName); } return auditImpl(mi, true); } else { if (logger.isDebugEnabled()) { logger.debug("UnknownService." + methodName); } return auditImpl(mi, true); } } else if (method.isAnnotationPresent(NotAuditable.class)) { if (logger.isDebugEnabled()) { logger.debug("Not Audited. " + serviceName + "." + methodName); } return mi.proceed(); } else { if (logger.isDebugEnabled()) { logger.debug("Unannotated service method " + serviceName + "." + methodName); } if (method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAnnotationPresent(PublicService.class)) { throw new RuntimeException( "Unannotated service method " + serviceName + "." + methodName); } else { return mi.proceed(); } } } finally { if (!auditInternal) { auditFlag.set(Boolean.FALSE); } } } else { return mi.proceed(); } } else { return mi.proceed(); } }